diff --git a/.travis.yml b/.travis.yml index e931e5386..4b7b99874 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,10 @@ env: # - FLAVOR=AR9X # - FLAVOR=SKY9X # - FLAVOR=9XRPRO + - FLAVOR=X3 - FLAVOR=X7 - FLAVOR=XLITE + - FLAVOR=XLITES - FLAVOR=X9 # - FLAVOR=X9D # - FLAVOR=X9D+ diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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 +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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 +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 +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. + + 13. Use with the GNU Affero General Public License. + + 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. + + 14. Revised Versions 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 +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. + + 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. + + 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. + + 15. Disclaimer of Warranty. + + 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. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +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 +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 + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +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: + + Copyright (C) + This program 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". + + 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 +. + + 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 +. diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 25b33b98d..a51151d4f 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -96,6 +96,7 @@ const int Boards::getEEpromSize(Board::Type board) case BOARD_9XRPRO: case BOARD_AR9X: return EESIZE_9XRPRO; + case BOARD_TARANIS_XLITES: case BOARD_TARANIS_XLITE: case BOARD_TARANIS_X7: case BOARD_TARANIS_X9D: @@ -124,6 +125,7 @@ const int Boards::getFlashSize(Type board) case BOARD_9XRPRO: case BOARD_AR9X: return FSIZE_9XRPRO; + case BOARD_TARANIS_XLITES: case BOARD_TARANIS_XLITE: case BOARD_TARANIS_X7: case BOARD_TARANIS_X9D: @@ -145,7 +147,19 @@ const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index) if (index < 0) return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM}; - if (IS_TARANIS_XLITE(board)) { + if (IS_TARANIS_XLITES(board)) { + const Board::SwitchInfo switches[] = { + {SWITCH_3POS, "SA"}, + {SWITCH_3POS, "SB"}, + {SWITCH_2POS, "SC"}, + {SWITCH_2POS, "SD"}, + {SWITCH_TOGGLE, "SE"}, + {SWITCH_TOGGLE, "SF"} + }; + if (index < DIM(switches)) + return switches[index]; + } + else if (IS_TARANIS_XLITE(board)) { const Board::SwitchInfo switches[] = { {SWITCH_3POS, "SA"}, {SWITCH_3POS, "SB"}, @@ -155,7 +169,7 @@ const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index) if (index < DIM(switches)) return switches[index]; } - if (IS_TARANIS_X7(board)) { + else if (IS_TARANIS_X7(board)) { const Board::SwitchInfo switches[] = { {SWITCH_3POS, "SA"}, {SWITCH_3POS, "SB"}, @@ -246,7 +260,7 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability) return getCapability(board, Board::Sticks) + getCapability(board, Board::Pots) + getCapability(board, Board::Sliders) + getCapability(board, Board::MouseAnalogs); case MultiposPots: - return IS_HORUS_OR_TARANIS(board) ? 3 : 0; + return IS_HORUS_OR_TARANIS(board) ? getCapability(board, Board::Pots) : 0; case MultiposPotsPositions: return IS_HORUS_OR_TARANIS(board) ? 6 : 0; @@ -256,6 +270,8 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability) return 18; else if (IS_TARANIS_X7(board)) return 6; + else if (IS_TARANIS_XLITES(board)) + return 6; else if (IS_TARANIS_XLITE(board)) return 4; else if (IS_HORUS_OR_TARANIS(board)) @@ -405,6 +421,8 @@ const QString Boards::getBoardName(Board::Type board) return "Taranis X7/X7S"; case BOARD_TARANIS_XLITE: return "Taranis X-Lite"; + case BOARD_TARANIS_XLITES: + return "Taranis X-Lite S"; case BOARD_TARANIS_X9D: return "Taranis X9D"; case BOARD_TARANIS_X9DP: diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 885da2fc3..87f9733e0 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -46,6 +46,7 @@ namespace Board { BOARD_X12S, BOARD_X10, BOARD_TARANIS_XLITE, + BOARD_TARANIS_XLITES, BOARD_ENUM_COUNT }; @@ -186,14 +187,15 @@ class Boards #define IS_2560(board) (board==Board::BOARD_GRUVIN9X || board==Board::BOARD_MEGA2560) #define IS_SKY9X(board) (board==Board::BOARD_SKY9X || board==Board::BOARD_9XRPRO || board==Board::BOARD_AR9X) #define IS_9XRPRO(board) (board==Board::BOARD_9XRPRO) -#define IS_TARANIS_XLITE(board) (board==Board::BOARD_TARANIS_XLITE) +#define IS_TARANIS_XLITE(board) (board==Board::BOARD_TARANIS_XLITE || board==Board::BOARD_TARANIS_XLITES) +#define IS_TARANIS_XLITES(board) (board==Board::BOARD_TARANIS_XLITES) #define IS_TARANIS_X7(board) (board==Board::BOARD_TARANIS_X7) #define IS_TARANIS_X9(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E) #define IS_TARANIS_X9D(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP) #define IS_TARANIS_PLUS(board) (board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E) #define IS_TARANIS_X9E(board) (board==Board::BOARD_TARANIS_X9E) -#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)) -#define IS_TARANIS_SMALL(board) (board==Board::BOARD_TARANIS_X7 || board==Board::BOARD_TARANIS_XLITE) +#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_XLITES(board)) +#define IS_TARANIS_SMALL(board) (board==Board::BOARD_TARANIS_X7 || board==Board::BOARD_TARANIS_XLITE || board==Board::BOARD_TARANIS_XLITES) #define IS_TARANIS_NOT_X9E(board) (IS_TARANIS(board) && !IS_TARANIS_X9E(board)) #define IS_HORUS_X12S(board) (board==Board::BOARD_X12S) #define IS_HORUS_X10(board) (board==Board::BOARD_X10) diff --git a/companion/src/firmwares/eepromimportexport.h b/companion/src/firmwares/eepromimportexport.h index 69944cba7..30cd2a045 100644 --- a/companion/src/firmwares/eepromimportexport.h +++ b/companion/src/firmwares/eepromimportexport.h @@ -387,7 +387,7 @@ class CharField: public DataField { }; static const char specialCharsTab[] = "_-.,"; -static inline int8_t char2idx(char c) +static inline int8_t char2zchar(char c) { if (c==' ') return 0; if (c>='A' && c<='Z') return 1+c-'A'; @@ -401,7 +401,7 @@ static inline int8_t char2idx(char c) } #define ZCHAR_MAX 40 -static inline char idx2char(int8_t idx) +static inline char zchar2char(int8_t idx) { if (idx == 0) return ' '; if (idx < 0) { @@ -429,7 +429,7 @@ class ZCharField: public DataField { int b = 0; int len = strlen(field); for (int i=0; i=len ? 0 : char2idx(field[i]); + int idx = i>=len ? 0 : char2zchar(field[i]); for (int j=0; j<8; j++, b++) { if (idx & (1<(this, generalData.jitterFilter)); internalField.Append(new BoolField<1>(this, generalData.disableRssiPoweroffAlarm)); internalField.Append(new UnsignedField<2>(this, generalData.usbMode)); - internalField.Append(new SpareBitsField<3>(this)); + internalField.Append(new UnsignedField<2>(this, generalData.jackMode)); + internalField.Append(new SpareBitsField<1>(this)); } else { internalField.Append(new SpareBitsField<7>(this)); diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h index 35c571787..ee840cc77 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.h +++ b/companion/src/firmwares/opentx/opentxeeprom.h @@ -33,6 +33,7 @@ #define TARANIS_X9E_VARIANT 0x8000 #define TARANIS_X7_VARIANT 0x4000 #define TARANIS_XLITE_VARIANT 0x2000 +#define TARANIS_XLITES_VARIANT 0x1000 #define SIMU_STOCK_VARIANTS (GVARS_VARIANT|FRSKY_VARIANT) #define SIMU_M128_VARIANTS (M128_VARIANT|SIMU_STOCK_VARIANTS) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index c9c35e251..30ee2de1b 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -317,6 +317,9 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u else if (IS_TARANIS_X7(board)) { variant |= TARANIS_X7_VARIANT; } + else if (IS_TARANIS_XLITES(board)) { + variant |= TARANIS_XLITES_VARIANT; + } else if (IS_TARANIS_XLITE(board)) { variant |= TARANIS_XLITE_VARIANT; } @@ -691,6 +694,8 @@ int OpenTxFirmware::getCapability(::Capability capability) return TARANIS_X9E_VARIANT; else if (IS_TARANIS_X7(board)) return TARANIS_X7_VARIANT; + else if (IS_TARANIS_XLITES(board)) + return TARANIS_XLITES_VARIANT; else if (IS_TARANIS_XLITE(board)) return TARANIS_XLITE_VARIANT; else @@ -708,6 +713,8 @@ int OpenTxFirmware::getCapability(::Capability capability) return id.contains("danger") ? 1 : 0; case HasModelCategories: return IS_HORUS(board); + case HasSwitchableJack: + return IS_TARANIS_XLITES(board); default: return 0; } @@ -921,6 +928,11 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari variantError = true; } } + else if (IS_TARANIS_XLITES(board)) { + if (variant != TARANIS_XLITES_VARIANT) { + variantError = true; + } + } else if (IS_TARANIS_XLITE(board)) { if (variant != TARANIS_XLITE_VARIANT) { variantError = true; @@ -1165,6 +1177,12 @@ void registerOpenTxFirmwares() addOpenTxTaranisOptions(firmware, false); registerOpenTxFirmware(firmware); + /* FrSky X-Lite S board */ + firmware = new OpenTxFirmware("opentx-xlites", QCoreApplication::translate("Firmware", "FrSky Taranis X-Lite S"), BOARD_TARANIS_XLITES); + // firmware->addOption("stdr9m", QCoreApplication::translate("Firmware", "Use JR-sized R9M module")); + addOpenTxTaranisOptions(firmware); + registerOpenTxFirmware(firmware); + /* FrSky X-Lite board */ firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE); // firmware->addOption("stdr9m", Firmware::tr("Use JR-sized R9M module")); diff --git a/companion/src/generaledit/generalsetup.cpp b/companion/src/generaledit/generalsetup.cpp index d2265a009..b6bf20711 100644 --- a/companion/src/generaledit/generalsetup.cpp +++ b/companion/src/generaledit/generalsetup.cpp @@ -151,13 +151,21 @@ ui(new Ui::GeneralSetup) ui->adjustRTC->hide(); } - if (IS_STM32(firmware->getBoard())){ + if (IS_STM32(firmware->getBoard())) { ui->usbModeCB->setCurrentIndex(generalSettings.usbMode); } else { ui->usbModeLabel->hide(); ui->usbModeCB->hide(); } + + if (firmware->getCapability(HasSwitchableJack)) { + ui->jackModeCB->setCurrentIndex(generalSettings.jackMode); + } + else { + ui->jackModeLabel->hide(); + ui->jackModeCB->hide(); + } if (!firmware->getCapability(OptrexDisplay)) { ui->label_displayType->hide(); @@ -353,6 +361,15 @@ void GeneralSetupPanel::on_usbModeCB_currentIndexChanged(int index) } } +void GeneralSetupPanel::on_jackModeCB_currentIndexChanged(int index) +{ + if (!lock) { + generalSettings.jackMode = ui->jackModeCB->currentIndex(); + emit modified(); + } +} + + void GeneralSetupPanel::on_backlightColor_SL_valueChanged() { if (!lock) { diff --git a/companion/src/generaledit/generalsetup.h b/companion/src/generaledit/generalsetup.h index 80a63d027..d3f800714 100644 --- a/companion/src/generaledit/generalsetup.h +++ b/companion/src/generaledit/generalsetup.h @@ -60,6 +60,7 @@ class GeneralSetupPanel : public GeneralPanel void on_hapticLengthCB_currentIndexChanged(int index); void on_backlightswCB_currentIndexChanged(int index); void on_usbModeCB_currentIndexChanged(int index); + void on_jackModeCB_currentIndexChanged(int index); void on_backlightColor_SL_valueChanged(); void on_mavbaud_CB_currentIndexChanged(int index); void on_voiceLang_CB_currentIndexChanged(int index); diff --git a/companion/src/generaledit/generalsetup.ui b/companion/src/generaledit/generalsetup.ui index a30bf446f..5537004bc 100644 --- a/companion/src/generaledit/generalsetup.ui +++ b/companion/src/generaledit/generalsetup.ui @@ -29,10 +29,10 @@ QLayout::SetMinimumSize - + 0 - + 0 @@ -1121,906 +1121,43 @@ p, li { white-space: pre-wrap; } QLayout::SetDefaultConstraint - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - <!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=" text-decoration: underline;">Warnings</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;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> - + + - - - - true + GPS Coordinates - - - - - 0 - 0 - - - - - 0 - 0 - - - - RSSI Poweroff Warning - - - - - - - - 0 - 0 - - - - - 0 - 22 - - + + - - Beeper volume - -0 - Quiet. No beeps at all. -1 - No Keys. Normal beeps but menu keys do not beep. -2 - Normal. -3 - Loud. -4 - Extra loud. - - - - Quiet - - - - - Alarms Only - - - - - No Keys - - - - - All - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Beeper Mode - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - X-Short - - - - - Short - - - - - Normal - - - - - Long - - - - - X-Long - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Beeper Length - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Haptic Mode - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Measurement Units - - - - - - - - 0 - 0 - - - - Play Delay (switch mid position) - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - X-Short - - - - - Short - - - - - Normal - - - - - Long - - - - - X-Long - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - <!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=" text-decoration: underline;">Warnings</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;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> - - - - - - true - - - - - - - - hh° (N/S) mm' ss''.dd - - - - - NMEA - - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - 16777215 - 16777215 - - - - <!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=" text-decoration: underline;">Warnings</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;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> - - - - - - true - - - - - - - - 4800 Baud - - - - - 9600 Baud - - - - - 14400 Baud - - - - - 19200 Baud - - - - - 38400 Baud - - - - - 57600 Baud - - - - - 76800 Baud - - - - - 115200 Baud - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Show splash screen on startup - - - Show splash screen on startup - - - - - - - - - - - 0 - 0 - - - - - --- - - - - - 2s - - - - - 3s - - - - - 4s - - - - - 6s - - - - - 8s - - - - - 10s - - - - - 15s - - - - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - - - - - - If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LCD Screen Contrast</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Values can be 20-45</span></p></body></html> - min - - - 120 - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - Standard - - - - - Optrex - - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - - - - - - Battery warning voltage. -This is the threashhold where the battery warning sounds. - -Acceptable values are 5v..10v - - - - - - V - - - 1 + ms - 4.000000000000000 + 0 - 12.000000000000000 + 1000 - 0.100000000000000 - - - 9.600000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - - - - - - - - 10 - - 45 - - 25 - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - -2 - - - 2 - - - 1 - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 0 - 22 - - - - - Quiet - - - - - Only Alarms - - - - - No Keys - - - - - All - - - - - - - - - 0 - 0 - - - - MAVLink Baud Rate - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Haptic Length - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - - - Battery Warning - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - "No Sound" Warning - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - LCD Display Type - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Haptic Strength - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Battery Meter Range - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - Contrast - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Show Splash Screen on Startup - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Low EEPROM Warning - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Inactivity Timer + 0 @@ -2086,8 +1223,8 @@ Acceptable values are 5v..10v - - + + @@ -2095,34 +1232,55 @@ Acceptable values are 5v..10v - <!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-size:8pt;">LCD Screen Contrast</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Values can be 20-45</span></p></body></html> + Mode selection: + +Mode 1: + Left stick: Elevator, Rudder + Right stick: Throttle, Aileron + +Mode 2: + Left stick: Throttle, Rudder + Right stick: Elevator, Aileron + +Mode 3: + Left stick: Elevator, Aileron + Right stick: Throttle, Rudder + +Mode 4: + Left stick: Throttle, Aileron + Right stick: Elevator, Rudder + + - - ms - - - 0 - - - 1000 - - - 10 - - - 0 + + 1 + + + Mode 1 (RUD ELE THR AIL) + + + + + Mode 2 (RUD THR ELE AIL) + + + + + Mode 3 (AIL ELE THR RUD) + + + + + Mode 4 (AIL THR ELE RUD) + + - - + + - GPS Coordinates + Stick Mode @@ -2153,13 +1311,6 @@ p, li { white-space: pre-wrap; } - - - - Stick Mode - - - @@ -2296,67 +1447,6 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - Mode selection: - -Mode 1: - Left stick: Elevator, Rudder - Right stick: Throttle, Aileron - -Mode 2: - Left stick: Throttle, Rudder - Right stick: Elevator, Aileron - -Mode 3: - Left stick: Elevator, Aileron - Right stick: Throttle, Rudder - -Mode 4: - Left stick: Throttle, Aileron - Right stick: Elevator, Rudder - - - - - 1 - - - - Mode 1 (RUD ELE THR AIL) - - - - - Mode 2 (RUD THR ELE AIL) - - - - - Mode 3 (AIL ELE THR RUD) - - - - - Mode 4 (AIL THR ELE RUD) - - - - - - - - USB Mode - - - @@ -2381,6 +1471,942 @@ Mode 4: + + + + USB Mode + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + <!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=" text-decoration: underline;">Warnings</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;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> + + + + + + true + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + RSSI Poweroff Warning + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Beeper Length + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + + + + + + Beeper volume + +0 - Quiet. No beeps at all. +1 - No Keys. Normal beeps but menu keys do not beep. +2 - Normal. +3 - Loud. +4 - Extra loud. + + + + Quiet + + + + + Alarms Only + + + + + No Keys + + + + + All + + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + X-Short + + + + + Short + + + + + Normal + + + + + Long + + + + + X-Long + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Beeper Mode + + + + + + + Measurement Units + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Haptic Mode + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Play Delay (switch mid position) + + + + + + + + 4800 Baud + + + + + 9600 Baud + + + + + 14400 Baud + + + + + 19200 Baud + + + + + 38400 Baud + + + + + 57600 Baud + + + + + 76800 Baud + + + + + 115200 Baud + + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + X-Short + + + + + Short + + + + + Normal + + + + + Long + + + + + X-Long + + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + 16777215 + 16777215 + + + + <!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=" text-decoration: underline;">Warnings</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;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> + + + + + + true + + + + + + + + hh° (N/S) mm' ss''.dd + + + + + NMEA + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + <!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=" text-decoration: underline;">Warnings</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;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These will define startup warnings.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Throttle warning - will alert if the throttle is not at idle during startup</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Switch warning - will alert if switches are not in their defaul position</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory warning - will alert if there's not a lot of memory left</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Silent mode warning - will alert you if the beeper is set to quiet (0)</p></body></html> + + + + + + true + + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Show splash screen on startup + + + Show splash screen on startup + + + + + + + + + + + 0 + 0 + + + + + --- + + + + + 2s + + + + + 3s + + + + + 4s + + + + + 6s + + + + + 8s + + + + + 10s + + + + + 15s + + + + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + + + + + + If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. + + + min + + + 120 + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + Standard + + + + + Optrex + + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + + + + + + + + + 10 + + + 45 + + + 25 + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + + + + + + Battery warning voltage. +This is the threashhold where the battery warning sounds. + +Acceptable values are 5v..10v + + + + + + V + + + 1 + + + 4.000000000000000 + + + 12.000000000000000 + + + 0.100000000000000 + + + 9.600000000000000 + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + -2 + + + 2 + + + 1 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + Quiet + + + + + Only Alarms + + + + + No Keys + + + + + All + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + "No Sound" Warning + + + + + + + + 0 + 0 + + + + MAVLink Baud Rate + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + + + Battery Warning + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Haptic Length + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + LCD Display Type + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Battery Meter Range + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Haptic Strength + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Inactivity Timer + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Low EEPROM Warning + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Show Splash Screen on Startup + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + Contrast + + + + + + + Jack Mode + + + + + + + + Ask on Connect + + + + + Audio + + + + + Trainer + + + + diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 4ad053c73..5d059f4db 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -77,6 +77,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato radioUiWidget = new SimulatedUIWidgetX9(simulator, this); break; case Board::BOARD_TARANIS_XLITE: + case Board::BOARD_TARANIS_XLITES: radioUiWidget = new SimulatedUIWidgetXLITE(simulator, this); break; case Board::BOARD_TARANIS_X9E: @@ -108,7 +109,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato vJoyLeft = new VirtualJoystickWidget(this, 'L'); ui->leftStickLayout->addWidget(vJoyLeft); - vJoyRight = new VirtualJoystickWidget(this, 'R', (m_board == Board::BOARD_TARANIS_XLITE ? false : true)); // TODO: maybe remove trims for both joysticks and add a cross in the middle? + vJoyRight = new VirtualJoystickWidget(this, 'R', (m_board == Board::BOARD_TARANIS_XLITE || m_board == Board::BOARD_TARANIS_XLITES ? false : true)); // TODO: maybe remove trims for both joysticks and add a cross in the middle? ui->rightStickLayout->addWidget(vJoyRight); connect(vJoyLeft, &VirtualJoystickWidget::valueChange, this, &SimulatorWidget::onRadioWidgetValueChange); diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 713655f44..60646540b 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -1,7 +1,7 @@ include(CMakeForceCompiler) include(Bitmaps) -set(PCB_TYPES X7 XLITE X9D X9D+ X9E X10 X12S SKY9X 9XRPRO AR9X) +set(PCB_TYPES X3 X7 XLITE XLITES X9D X9D+ X9E X10 X12S SKY9X 9XRPRO AR9X) set(GUI_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL) set(TTS_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL RU) @@ -46,8 +46,6 @@ option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF) option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF) option(NANO "Use nano newlib and binalloc") option(NIGHTLY_BUILD_WARNING "Warn this is a nightly build" OFF) -option(MODULE_R9M_FLEX_FW "Add R9M options for non certified firmwwares" OFF) -option(PXX2 "Enable PXX v2 support" OFF) # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -82,7 +80,7 @@ set(FATFS_SRC if(PCB STREQUAL X12S OR PCB STREQUAL X10) include(targets/horus/CMakeLists.txt) -elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL XLITE) +elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X3 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) @@ -133,10 +131,7 @@ else() add_definitions(-DEEPROM -DEEPROM_RAW) endif() -if(ARCH STREQUAL ARM AND NOT PCB STREQUAL X12S AND NOT PCB STREQUAL X10 AND NOT PCB STREQUAL XLITE) - add_definitions(-DEEPROM_CONVERSIONS) - set(SRC ${SRC} storage/eeprom_conversions.cpp) -endif() +include(storage/conversions/CMakeLists.txt) add_definitions(-DFLAVOUR="${FLAVOUR}") @@ -313,14 +308,6 @@ if(NIGHTLY_BUILD_WARNING) add_definitions(-DNIGHTLY_BUILD_WARNING) endif(NIGHTLY_BUILD_WARNING) -if(MODULE_R9M_FLEX_FW) - add_definitions(-DMODULE_R9M_FLEX_FW) -endif() - -if(PXX2) - add_definitions(-DPXX2) -endif() - set(SRC ${SRC} opentx.cpp @@ -458,7 +445,7 @@ if(NOT MSVC) set(SRC ${SRC} bin_allocator.cpp) endif() - if(PCB STREQUAL XLITE OR PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X7 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 X7 OR PCB STREQUAL X3 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(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader) diff --git a/radio/src/audio_arm.cpp b/radio/src/audio.cpp similarity index 100% rename from radio/src/audio_arm.cpp rename to radio/src/audio.cpp diff --git a/radio/src/audio_arm.h b/radio/src/audio.h similarity index 100% rename from radio/src/audio_arm.h rename to radio/src/audio.h diff --git a/radio/src/bitfield.h b/radio/src/bitfield.h new file mode 100644 index 000000000..379d4280f --- /dev/null +++ b/radio/src/bitfield.h @@ -0,0 +1,74 @@ +/* + * 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 + * + * This file is based on work published at http://www.coranac.com/documents/working-with-bits-and-bitfields + * + * 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 BITFIELD_H +#define BITFIELD_H + +#include + +// A set of bitfield handling macros + +template +inline T BF_BIT(uint8_t n) +{ + return T(1) << n; +} + +#define BF_BIT_GET(y, mask) ( y & (mask) ) +#define BF_BIT_SET(y, mask) ( y |= (mask) ) +#define BF_BIT_CLEAR(y, mask) ( y &= ~(mask) ) +#define BF_BIT_FLIP(y, mask) ( y ^= (mask) ) +#define BF_SINGLE_BIT_GET(y, i) BF_BIT_GET(y, BF_BIT(i)) +#define BF_SINGLE_BIT_SET(y, i) BF_BIT_SET(y, BF_BIT(i)) + +//! Create a bitmask of length 'len'. +template +inline T BF_BITMASK(uint8_t len) +{ + return BF_BIT(len) - 1; +} + +//! Create a bitfield mask of length 'len' starting at bit 'start'. +template +inline T BF_MASK(uint8_t start, uint8_t len) +{ + return BF_BITMASK(len) << start; +} + +//! Prepare a bitmask for insertion or combining. +template +inline T BF_PREP(T x, uint8_t start, uint8_t len) +{ + return (x & BF_BITMASK(len)) << start; +} + +//! Extract a bitfield of length 'len' starting at bit 'start' from 'y'. +#define BF_GET(y, start, len) ( ((y)>>(start)) & BF_BITMASK(len) ) + +//! Insert 'len' bits of 'x 'into 'y', starting at bit 'start' from 'y'. +template +inline T BF_SET(T to, T from, uint8_t start, uint8_t len) +{ + return (to & ~BF_MASK(start, len)) | BF_PREP(from, start, len); +} + +#endif //BITFIELD_H diff --git a/radio/src/bluetooth.cpp b/radio/src/bluetooth.cpp index 50bc769bd..95245ffcc 100644 --- a/radio/src/bluetooth.cpp +++ b/radio/src/bluetooth.cpp @@ -71,32 +71,50 @@ char * bluetoothReadline(bool error_reset) if (!btRxFifo.pop(byte)) { #if defined(PCBX9E) && !defined(USEHORUSBT) // X9E BT module can get unresponsive TRACE("NO RESPONSE FROM BT MODULE"); +#endif + return nullptr; + } + + TRACE_NOCRLF("%02X ", byte); + +#if 0 + if (error_reset && byte == 'R' && bluetoothBufferIndex == 4 && memcmp(bluetoothBuffer, "ERRO", 4)) { +#if defined(PCBX9E) // X9E enter BT reset loop if following code is implemented + TRACE("BT Error..."); +#else + TRACE("BT Reset..."); + bluetoothBufferIndex = 0; + bluetoothDone(); + bluetoothState = BLUETOOTH_STATE_OFF; + bluetoothWakeupTime = get_tmr10ms() + 100; /* 1s */ #endif return NULL; } - TRACE_NOCRLF("%02X ", byte); + else +#endif + if (byte == '\n') { if (bluetoothBufferIndex > 2 && bluetoothBuffer[bluetoothBufferIndex-1] == '\r') { bluetoothBuffer[bluetoothBufferIndex-1] = '\0'; bluetoothBufferIndex = 0; TRACE("BT< %s", bluetoothBuffer); if (error_reset && !strcmp((char *)bluetoothBuffer, "ERROR")) { -#if defined(PCBX9E) // X9E enter BT reset loop if following code is implemented - TRACE("BT error..."); +#if defined(PCBX9E) // X9E enter BT reset loop if following code is implemented + TRACE("BT Error..."); #else TRACE("BT Reset..."); bluetoothDone(); bluetoothState = BLUETOOTH_STATE_OFF; bluetoothWakeupTime = get_tmr10ms() + 100; /* 1s */ #endif - return NULL; + return nullptr; } else { - if (!strncmp((char *)bluetoothBuffer, "Central:", 8)) - strcpy(bluetoothLocalAddr, (char *)bluetoothBuffer+8); - else if (!strncmp((char *)bluetoothBuffer, "Peripheral:", 11)) - strcpy(bluetoothLocalAddr, (char *)bluetoothBuffer+11); - return (char *)bluetoothBuffer; + if (!memcmp(bluetoothBuffer, "Central:", 8)) + strcpy(bluetoothLocalAddr, (char *) bluetoothBuffer + 8); + else if (!memcmp(bluetoothBuffer, "Peripheral:", 11)) + strcpy(bluetoothLocalAddr, (char *) bluetoothBuffer + 11); + return (char *) bluetoothBuffer; } } else { @@ -212,7 +230,7 @@ void bluetoothSendTrainer() { int16_t PPM_range = g_model.extendedLimits ? 640*2 : 512*2; - int firstCh = g_model.moduleData[TRAINER_MODULE].channelsStart; + int firstCh = g_model.trainerData.channelsStart; int lastCh = firstCh + 8; uint8_t * cur = bluetoothBuffer; @@ -280,7 +298,7 @@ void bluetoothWakeup(void) uint8_t len = ZLEN(g_eeGeneral.bluetoothName); if (len > 0) { for (int i = 0; i < len; i++) { - *cur++ = idx2char(g_eeGeneral.bluetoothName[i]); + *cur++ = zchar2char(g_eeGeneral.bluetoothName[i]); } } else { @@ -361,11 +379,11 @@ void bluetoothWakeup() bluetoothWakeupTime = now + 10; /* 100ms */ } else if (bluetoothState == BLUETOOTH_STATE_CONNECTED) { - if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH) { + if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH) { bluetoothReceiveTrainer(); } else { - if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH) { + if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH) { bluetoothSendTrainer(); bluetoothWakeupTime = now + 2; /* 20ms */ } @@ -374,20 +392,23 @@ void bluetoothWakeup() } else { char * line = bluetoothReadline(); + if (line) { + TRACE("BT %s", line); + } if (bluetoothState == BLUETOOTH_STATE_BAUDRATE_INIT) { char command[32]; char * cur = strAppend(command, BLUETOOTH_COMMAND_NAME); uint8_t len = ZLEN(g_eeGeneral.bluetoothName); if (len > 0) { for (int i = 0; i < len; i++) { - *cur++ = idx2char(g_eeGeneral.bluetoothName[i]); + *cur++ = zchar2char(g_eeGeneral.bluetoothName[i]); } } else { #if defined(PCBHORUS) cur = strAppend(cur, "Horus"); #else - cur = strAppend(cur, "Taranis"); + cur = strAppend(cur, "taranis"); // TODO capital letter once allowed by BT module #endif } strAppend(cur, "\r\n"); @@ -395,11 +416,11 @@ void bluetoothWakeup() bluetoothState = BLUETOOTH_STATE_NAME_SENT; } else if (bluetoothState == BLUETOOTH_STATE_NAME_SENT && (!strncmp(line, "OK+", 3) || !strncmp(line, "Central:", 8) || !strncmp(line, "Peripheral:", 11))) { - bluetoothWriteString("AT+TXPW3\r\n"); + bluetoothWriteString("AT+TXPW\r\n"); bluetoothState = BLUETOOTH_STATE_POWER_SENT; } else if (bluetoothState == BLUETOOTH_STATE_POWER_SENT && (!strncmp(line, "Central:", 8) || !strncmp(line, "Peripheral:", 11))) { - if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH) + if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH) bluetoothWriteString("AT+ROLE1\r\n"); else bluetoothWriteString("AT+ROLE0\r\n"); @@ -430,7 +451,7 @@ void bluetoothWakeup() else if ((bluetoothState == BLUETOOTH_STATE_IDLE || bluetoothState == BLUETOOTH_STATE_DISCONNECTED || bluetoothState == BLUETOOTH_STATE_CONNECT_SENT) && !strncmp(line, "Connected:", 10)) { strcpy(bluetoothDistantAddr, &line[10]); // TODO quick & dirty bluetoothState = BLUETOOTH_STATE_CONNECTED; - if (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH) { + if (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH) { bluetoothWakeupTime += 500; // it seems a 5s delay is needed before sending the 1st frame } } diff --git a/radio/src/bluetooth.h b/radio/src/bluetooth.h index f0201e431..4be34b8e4 100644 --- a/radio/src/bluetooth.h +++ b/radio/src/bluetooth.h @@ -44,13 +44,6 @@ enum BluetoothStates { #define LEN_BLUETOOTH_ADDR 16 -#if (defined(PCBX7) || defined(PCBXLITE)) && !defined(SIMU) -extern uint8_t btChipPresent; -#define IS_BLUETOOTH_CHIP_PRESENT() (btChipPresent) -#else -#define IS_BLUETOOTH_CHIP_PRESENT() (true) -#endif - extern volatile uint8_t bluetoothState; extern char bluetoothLocalAddr[LEN_BLUETOOTH_ADDR+1]; extern char bluetoothDistantAddr[LEN_BLUETOOTH_ADDR+1]; diff --git a/radio/src/cli.h b/radio/src/cli.h index fdb96d6d1..a590e101c 100644 --- a/radio/src/cli.h +++ b/radio/src/cli.h @@ -28,7 +28,7 @@ extern uint8_t cliTracesEnabled; #ifdef __cplusplus #include "fifo.h" extern Fifo cliRxFifo; -#include "tasks_arm.h" +#include "tasks.h" extern RTOS_TASK_HANDLE cliTaskId; extern RTOS_DEFINE_STACK(cliStack, CLI_STACK_SIZE); #endif diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index c22d85869..b3854cbe0 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -21,6 +21,8 @@ #ifndef _DATACONSTANTS_H_ #define _DATACONSTANTS_H_ +#include "board.h" + #define NUM_STICKS 4 #if defined(EXPORT) @@ -44,7 +46,7 @@ #define MAX_SCRIPTS 9 #define MAX_INPUTS 32 #define MAX_TRAINER_CHANNELS 16 - #define MAX_TELEMETRY_SENSORS 32 + #define MAX_TELEMETRY_SENSORS 64 #define MAX_CUSTOM_SCREENS 5 #elif defined(PCBTARANIS) #define MAX_MODELS 60 @@ -70,20 +72,10 @@ #define MAX_TRAINER_CHANNELS 16 #define MAX_TELEMETRY_SENSORS 32 #else - #define MAX_MODELS 16 - #define MAX_OUTPUT_CHANNELS 16 // number of real output channels CH1-CH16 - #define MAX_FLIGHT_MODES 5 - #define MAX_MIXERS 32 - #define MAX_EXPOS 14 - #define MAX_LOGICAL_SWITCHES 12 - #define MAX_SPECIAL_FUNCTIONS 16 // number of functions assigned to switches - #define MAX_TRAINER_CHANNELS 8 - #define MAX_TELEMETRY_SENSORS 0 + #warning "Unknown board!" #endif - #define MAX_TIMERS 3 - -#define NUM_CYC 3 +#define MAX_TIMERS 3 #define NUM_CAL_PPM 4 enum CurveType { @@ -92,8 +84,7 @@ enum CurveType { CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM }; - #define MIN_POINTS_PER_CURVE 3 - +#define MIN_POINTS_PER_CURVE 3 #define MAX_POINTS_PER_CURVE 17 #if defined(PCBHORUS) @@ -133,6 +124,14 @@ enum CurveType { #define MAX_CURVE_POINTS 512 #endif +#if defined(PCBHORUS) + #define NUM_RECEIVERS 10 + #define MAX_RECEIVERS_PER_MODULE 5 +#else + #define NUM_RECEIVERS 4 + #define MAX_RECEIVERS_PER_MODULE 4 +#endif + #if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS) #define NUM_MODULES 2 #else @@ -191,8 +190,7 @@ enum BeeperMode { enum ModuleIndex { INTERNAL_MODULE, EXTERNAL_MODULE, - TRAINER_MODULE, - FLASHING_MODULE, + SPORT_MODULE, }; enum TrainerMode { TRAINER_MODE_MASTER_TRAINER_JACK, @@ -211,7 +209,7 @@ enum BeeperMode { enum ModuleIndex { EXTERNAL_MODULE, EXTRA_MODULE, - TRAINER_MODULE + SPORT_MODULE }; #endif @@ -224,12 +222,12 @@ enum BeeperMode { #endif #if defined(PCBTARANIS) || defined(PCBHORUS) -#define IS_INTERNAL_MODULE_ENABLED() (g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) + #define IS_INTERNAL_MODULE_ENABLED() (g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) #elif defined(PCBSKY9X) #define IS_INTERNAL_MODULE_ENABLED() (false) #endif -#define IS_EXTERNAL_MODULE_ENABLED() (g_model.moduleData[EXTERNAL_MODULE].type != MODULE_TYPE_NONE) +#define IS_EXTERNAL_MODULE_ENABLED() (g_model.moduleData[EXTERNAL_MODULE].type != MODULE_TYPE_NONE) enum UartModes { #if defined(CLI) || defined(DEBUG) @@ -256,7 +254,7 @@ enum UartModes { #define LEN_BLUETOOTH_NAME 10 #endif -#define TELEM_LABEL_LEN 4 +#define TELEM_LABEL_LEN 4 enum TelemetryUnit { UNIT_RAW, UNIT_VOLTS, @@ -358,7 +356,7 @@ enum SwitchSources { SWSRC_FIRST_SWITCH, -#if defined(PCBTARANIS) || defined(PCBHORUS) +#if defined(PCBHORUS) || defined(PCBTARANIS) SWSRC_SA0 = SWSRC_FIRST_SWITCH, SWSRC_SA1, SWSRC_SA2, @@ -371,22 +369,22 @@ enum SwitchSources { SWSRC_SD0, SWSRC_SD1, SWSRC_SD2, -#if !defined(PCBX7) && !defined(PCBXLITE) +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBXLITES) SWSRC_SE0, SWSRC_SE1, SWSRC_SE2, #endif -#if !defined(PCBXLITE) +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBX7) || defined(PCBXLITES) SWSRC_SF0, SWSRC_SF1, SWSRC_SF2, #endif -#if !defined(PCBX7) && !defined(PCBXLITE) +#if defined(PCBHORUS) || defined(PCBX9) SWSRC_SG0, SWSRC_SG1, SWSRC_SG2, #endif -#if !defined(PCBXLITE) +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBX7) SWSRC_SH0, SWSRC_SH1, SWSRC_SH2, @@ -423,15 +421,11 @@ enum SwitchSources { SWSRC_SR1, SWSRC_SR2, #endif -#if defined(PCBX9E) + SWSRC_LAST_SWITCH = SWSRC_FIRST_SWITCH + NUM_SWITCHES_POSITIONS - 1, +#if NUM_SWITCHES >= 8 SWSRC_TRAINER = SWSRC_SH2, - SWSRC_LAST_SWITCH = SWSRC_SR2, -#elif defined(PCBXLITE) - SWSRC_TRAINER = SWSRC_SD2, - SWSRC_LAST_SWITCH = SWSRC_SD2, #else - SWSRC_TRAINER = SWSRC_SH2, - SWSRC_LAST_SWITCH = SWSRC_SH2, + SWSRC_TRAINER = SWSRC_LAST_SWITCH, #endif #else // neither Taranis nor Horus SWSRC_ID0 = SWSRC_FIRST_SWITCH, @@ -560,6 +554,9 @@ enum MixSources { MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1") MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2") MIXSRC_LAST_POT = MIXSRC_POT2, +#elif defined(PCBX3) + MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1") + MIXSRC_LAST_POT = MIXSRC_POT1, #elif defined(PCBTARANIS) MIXSRC_POT1 = MIXSRC_FIRST_POT, LUA_EXPORT("s1", "Potentiometer 1") MIXSRC_POT2, LUA_EXPORT("s2", "Potentiometer 2") @@ -588,9 +585,9 @@ enum MixSources { MIXSRC_MAX, MIXSRC_FIRST_HELI, - MIXSRC_CYC1 = MIXSRC_FIRST_HELI, LUA_EXPORT("cyc1", "Cyclic 1") - MIXSRC_CYC2, LUA_EXPORT("cyc2", "Cyclic 2") - MIXSRC_CYC3, LUA_EXPORT("cyc3", "Cyclic 3") + MIXSRC_CYC1 = MIXSRC_FIRST_HELI, LUA_EXPORT("cyc1", "Cyclic 1") + MIXSRC_CYC2, LUA_EXPORT("cyc2", "Cyclic 2") + MIXSRC_CYC3, LUA_EXPORT("cyc3", "Cyclic 3") MIXSRC_FIRST_TRIM, MIXSRC_TrimRud = MIXSRC_FIRST_TRIM, LUA_EXPORT("trim-rud", "Rudder trim") @@ -607,25 +604,23 @@ enum MixSources { MIXSRC_FIRST_SWITCH, -#if defined(PCBXLITE) +#if defined(PCBHORUS) || defined(PCBTARANIS) MIXSRC_SA = MIXSRC_FIRST_SWITCH, LUA_EXPORT("sa", "Switch A") MIXSRC_SB, LUA_EXPORT("sb", "Switch B") MIXSRC_SC, LUA_EXPORT("sc", "Switch C") MIXSRC_SD, LUA_EXPORT("sd", "Switch D") - MIXSRC_LAST_SWITCH = MIXSRC_SD, -#elif defined(PCBTARANIS) || defined(PCBHORUS) - MIXSRC_SA = MIXSRC_FIRST_SWITCH, LUA_EXPORT("sa", "Switch A") - MIXSRC_SB, LUA_EXPORT("sb", "Switch B") - MIXSRC_SC, LUA_EXPORT("sc", "Switch C") - MIXSRC_SD, LUA_EXPORT("sd", "Switch D") -#if !defined(PCBX7) +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBXLITES) MIXSRC_SE, LUA_EXPORT("se", "Switch E") #endif +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBX7) || defined(PCBXLITES) MIXSRC_SF, LUA_EXPORT("sf", "Switch F") -#if !defined(PCBX7) +#endif +#if defined(PCBHORUS) || defined(PCBX9) MIXSRC_SG, LUA_EXPORT("sg", "Switch G") #endif +#if defined(PCBHORUS) || defined(PCBX9) || defined(PCBX7) MIXSRC_SH, LUA_EXPORT("sh", "Switch H") +#endif #if defined(PCBX9E) MIXSRC_SI, LUA_EXPORT("si", "Switch I") MIXSRC_SJ, LUA_EXPORT("sj", "Switch J") @@ -637,9 +632,6 @@ enum MixSources { MIXSRC_SP, LUA_EXPORT("sp", "Switch P") MIXSRC_SQ, LUA_EXPORT("sq", "Switch Q") MIXSRC_SR, LUA_EXPORT("sr", "Switch R") - MIXSRC_LAST_SWITCH = MIXSRC_SR, -#else - MIXSRC_LAST_SWITCH = MIXSRC_SH, #endif #else MIXSRC_3POS = MIXSRC_FIRST_SWITCH, @@ -649,7 +641,6 @@ enum MixSources { MIXSRC_AIL, MIXSRC_GEA, MIXSRC_TRN, - MIXSRC_LAST_SWITCH = MIXSRC_TRN, #endif MIXSRC_FIRST_LOGICAL_SWITCH, MIXSRC_SW1 = MIXSRC_FIRST_LOGICAL_SWITCH, LUA_EXPORT_MULTIPLE("ls", "Logical switch L%d", MAX_LOGICAL_SWITCHES) @@ -703,10 +694,11 @@ enum MixSources { MIXSRC_LAST_TELEM = MIXSRC_FIRST_TELEM+3*MAX_TELEMETRY_SENSORS-1 }; -#define MIXSRC_FIRST (MIXSRC_NONE+1) -#define MIXSRC_LAST MIXSRC_LAST_CH -#define INPUTSRC_FIRST MIXSRC_Rud -#define INPUTSRC_LAST MIXSRC_LAST_TELEM +#define MIXSRC_FIRST (MIXSRC_NONE + 1) +#define MIXSRC_LAST MIXSRC_LAST_CH +#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + NUM_SWITCHES - 1) +#define INPUTSRC_FIRST MIXSRC_Rud +#define INPUTSRC_LAST MIXSRC_LAST_TELEM enum BacklightMode { e_backlight_mode_off = 0, @@ -803,4 +795,9 @@ enum BluetoothModes { BLUETOOTH_TRAINER, }; +// PXX2 constants +#define PXX2_LEN_REGISTRATION_ID 8 +#define PXX2_LEN_RX_NAME 8 +#define PXX2_MAX_RECEIVERS_PER_MODULE 3 + #endif // _DATACONSTANTS_H_ diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 44eb39f6a..f097f90c2 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -25,6 +25,7 @@ #include "board.h" #include "dataconstants.h" #include "definitions.h" +#include "bitfield.h" #if defined(PCBTARANIS) #define N_TARANIS_FIELD(x) @@ -385,14 +386,40 @@ PACK(struct TelemetrySensor { uint32_t param; }; NOBACKUP( - void init(const char *label, uint8_t unit=UNIT_RAW, uint8_t prec=0); - void init(uint16_t id); - bool isAvailable() const; - int32_t getValue(int32_t value, uint8_t unit, uint8_t prec) const; - bool isConfigurable() const; - bool isPrecConfigurable() const; - int32_t getPrecMultiplier() const; - int32_t getPrecDivisor() const); + void init(const char *label, uint8_t unit=UNIT_RAW, uint8_t prec=0); + void init(uint16_t id); + bool isAvailable() const; + int32_t getValue(int32_t value, uint8_t unit, uint8_t prec) const; + bool isConfigurable() const; + bool isPrecConfigurable() const; + int32_t getPrecMultiplier() const; + int32_t getPrecDivisor() const; + ); +}); + +/* + * Trainer module structure + */ + +PACK(struct TrainerModuleData { + uint8_t mode:3; + uint8_t spare:5; + uint8_t channelsStart; + int8_t channelsCount; // 0=8 channels + int8_t frameLength; + int8_t delay:6; + uint8_t pulsePol:1; +}); + +/* + * Receiver structure + */ + +PACK(struct ReceiverData { + uint8_t used:1; + uint8_t telemetry:1; + uint8_t dirty:6; + char name[PXX2_LEN_RX_NAME]; }); /* @@ -406,10 +433,19 @@ PACK(struct ModuleData { int8_t rfProtocol:4; uint8_t channelsStart; int8_t channelsCount; // 0=8 channels - uint8_t failsafeMode:4; // only 3 bits used - uint8_t subType:3; - uint8_t invertedSerial:1; // telemetry serial inverted from standard - int16_t failsafeChannels[MAX_OUTPUT_CHANNELS]; + union { + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t subType:3; + uint8_t invertedSerial:1; // telemetry serial inverted from standard + }; + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t freq:2; + uint8_t region:2; + } r9m; + }; + union { struct { int8_t delay:6; @@ -440,6 +476,28 @@ PACK(struct ModuleData { uint8_t spare2:1; int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms) } sbus); + NOBACKUP(PACK(struct { + uint8_t power:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W + uint8_t external_antenna:1; // false = internal antenna, true = external antenna +#if defined(PCBHORUS) + uint8_t spare:5; + uint32_t receivers; // max 5 receivers per module and 10 receivers in total (4bits per receiver with 0 = unused) +#else + uint8_t spare:1; + uint16_t receivers:12; // max 4 receivers per module and 4 receivers in total (3bits per receiver with 0 = unused) +#endif + NOBACKUP(inline uint8_t getReceiverSlot(uint8_t receiver) { + return (receivers >> (3 * receiver)) & 0b111; + }) + + NOBACKUP(inline void setReceiverSlot(uint8_t receiver, uint8_t slot) { + receivers = BF_SET(receivers, slot, 3 * receiver, 3); + }) + + NOBACKUP(inline void clearReceiverSlot(uint8_t receiver) { + setReceiverSlot(receiver, 0); + }) + }) pxx2); }; // Helper functions to set both of the rfProto protocol at the same time @@ -449,12 +507,10 @@ PACK(struct ModuleData { return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4); }) - NOBACKUP(inline void setMultiProtocol(uint8_t proto) - { + NOBACKUP(inline void setMultiProtocol(uint8_t proto) { rfProtocol = (uint8_t) (proto & 0x0f); multi.rfProtocolExtra = (proto & 0x30) >> 4; }) - }); /* @@ -501,10 +557,6 @@ typedef uint8_t swarnenable_t; swarnenable_t switchWarningEnable; #endif - #define MODEL_GVARS_DATA GVarData gvars[MAX_GVARS]; - - #define TELEMETRY_DATA NOBACKUP(FrSkyTelemetryData frsky); NOBACKUP(RssiAlarmData rssiAlarms); - #if defined(PCBHORUS) #include "gui/480x272/layout.h" #include "gui/480x272/topbar.h" @@ -518,23 +570,11 @@ PACK(struct CustomScreenData { NOBACKUP(Topbar::PersistentData topbarData); \ NOBACKUP(uint8_t view); #elif defined(PCBTARANIS) -#define CUSTOM_SCREENS_DATA \ + #define CUSTOM_SCREENS_DATA \ NOBACKUP(uint8_t view); #else -#define CUSTOM_SCREENS_DATA -// TODO other boards could have their custom screens here as well -#endif - -#if defined(PCBX12S) - #define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]); -#elif defined(PCBX10) - #define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]); NOBACKUP(uint8_t potsWarnSpares[NUM_DUMMY_ANAS]); -#elif defined(PCBTARANIS) - #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; -#elif defined(PCBSKY9X) - #define MODELDATA_EXTRA uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; uint8_t rxBattAlarms[2]; -#else - #define MODELDATA_EXTRA + #define CUSTOM_SCREENS_DATA + // TODO other boards could have their custom screens here as well #endif PACK(struct ModelData { @@ -568,11 +608,25 @@ PACK(struct ModelData { SWITCHES_WARNING_DATA - MODEL_GVARS_DATA + GVarData gvars[MAX_GVARS]; - TELEMETRY_DATA + NOBACKUP(FrSkyTelemetryData frsky); + NOBACKUP(RssiAlarmData rssiAlarms); - MODELDATA_EXTRA + NOBACKUP(uint8_t spare:6); + NOBACKUP(uint8_t potsWarnMode:2); + ModuleData moduleData[NUM_MODULES]; + ReceiverData receiverData[NUM_RECEIVERS]; + int16_t failsafeChannels[MAX_OUTPUT_CHANNELS]; + TrainerModuleData trainerData; + +#if defined(PCBHORUS) || defined(PCBTARANIS) + NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); +#endif + + NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); + NOBACKUP(uint8_t potsWarnEnabled); + NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS+NUM_DUMMY_ANAS]); NOBACKUP(TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS];) @@ -580,6 +634,7 @@ PACK(struct ModelData { CUSTOM_SCREENS_DATA + char modelRegistrationID[PXX2_LEN_REGISTRATION_ID]; }); /* @@ -616,30 +671,8 @@ PACK(struct TrainerData { #define SPLASH_MODE int8_t splashMode:3 #endif - #define EXTRA_GENERAL_FIELDS_ARM \ - NOBACKUP(uint8_t backlightBright); \ - NOBACKUP(uint32_t globalTimer); \ - NOBACKUP(uint8_t bluetoothBaudrate:4); \ - NOBACKUP(uint8_t bluetoothMode:4); \ - NOBACKUP(uint8_t countryCode); \ - NOBACKUP(uint8_t imperial:1); \ - NOBACKUP(uint8_t jitterFilter:1); /* 0 - active */\ - NOBACKUP(uint8_t disableRssiPoweroffAlarm:1); \ - NOBACKUP(uint8_t USBMode:2); \ - NOBACKUP(uint8_t spareExtraArm:3); \ - NOBACKUP(char ttsLanguage[2]); \ - NOBACKUP(int8_t beepVolume:4); \ - NOBACKUP(int8_t wavVolume:4); \ - NOBACKUP(int8_t varioVolume:4); \ - NOBACKUP(int8_t backgroundVolume:4); \ - NOBACKUP(int8_t varioPitch); \ - NOBACKUP(int8_t varioRange); \ - NOBACKUP(int8_t varioRepeat); \ - CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS]; - #if defined(PCBHORUS) #define EXTRA_GENERAL_FIELDS \ - EXTRA_GENERAL_FIELDS_ARM \ NOBACKUP(uint8_t serial2Mode:4); \ uint8_t slidersConfig:4; \ uint32_t switchConfig; \ @@ -659,7 +692,6 @@ PACK(struct TrainerData { #define BLUETOOTH_FIELDS #endif #define EXTRA_GENERAL_FIELDS \ - EXTRA_GENERAL_FIELDS_ARM \ uint8_t serial2Mode:4; \ uint8_t slidersConfig:4; \ uint8_t potsConfig; /* two bits per pot */\ @@ -671,7 +703,6 @@ PACK(struct TrainerData { BLUETOOTH_FIELDS #elif defined(PCBSKY9X) #define EXTRA_GENERAL_FIELDS \ - EXTRA_GENERAL_FIELDS_ARM \ int8_t txCurrentCalibration; \ int8_t temperatureWarn; \ uint8_t mAhWarn; \ @@ -683,7 +714,7 @@ PACK(struct TrainerData { char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \ char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; #else - #define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM + #define EXTRA_GENERAL_FIELDS #endif #if defined(PCBHORUS) @@ -697,9 +728,9 @@ PACK(struct TrainerData { #endif #if defined(BUZZER) - #define BUZZER_FIELD NOBACKUP(int8_t buzzerMode:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware) + #define BUZZER_FIELD int8_t buzzerMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware) #else - #define BUZZER_FIELD NOBACKUP(int8_t spareRadio:2); + #define BUZZER_FIELD int8_t spareRadio:2; #endif PACK(struct RadioData { @@ -743,16 +774,39 @@ PACK(struct RadioData { NOBACKUP(int8_t vBatMin); NOBACKUP(int8_t vBatMax); + NOBACKUP(uint8_t backlightBright); + NOBACKUP(uint32_t globalTimer); + NOBACKUP(uint8_t bluetoothBaudrate:4); + NOBACKUP(uint8_t bluetoothMode:4); + NOBACKUP(uint8_t countryCode); + NOBACKUP(uint8_t imperial:1); + NOBACKUP(uint8_t jitterFilter:1); /* 0 - active */ + NOBACKUP(uint8_t disableRssiPoweroffAlarm:1); + NOBACKUP(uint8_t USBMode:2); + NOBACKUP(uint8_t jackMode:2); + NOBACKUP(uint8_t spareExtraArm:1); + NOBACKUP(char ttsLanguage[2]); + NOBACKUP(int8_t beepVolume:4); + NOBACKUP(int8_t wavVolume:4); + NOBACKUP(int8_t varioVolume:4); + NOBACKUP(int8_t backgroundVolume:4); + NOBACKUP(int8_t varioPitch); + NOBACKUP(int8_t varioRange); + NOBACKUP(int8_t varioRepeat); + + CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS]; + EXTRA_GENERAL_FIELDS THEME_DATA + char ownerRegistrationID[PXX2_LEN_REGISTRATION_ID]; }); #undef SWITCHES_WARNING_DATA #undef MODEL_GVARS_DATA #undef TELEMETRY_DATA -#undef MODELDATA_EXTRA +#undef SCRIPTS_DATA #undef CUSTOM_SCREENS_DATA #undef SPLASH_MODE #undef EXTRA_GENERAL_FIELDS @@ -783,7 +837,7 @@ static inline void check_struct() /* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */ /* LEN_FUNCTION_NAME is the difference in CustomFunctionData */ -#if defined(PCBX7) || defined(PCBXLITE) +#if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) CHKSIZE(MixData, 20); CHKSIZE(ExpoData, 17); CHKSIZE(LimitData, 11); @@ -862,31 +916,39 @@ static inline void check_struct() CHKSIZE(LogicalSwitchData, 9); CHKSIZE(TelemetrySensor, 13); - CHKSIZE(ModuleData,70); + +#if defined(PCBHORUS) + CHKSIZE(ModuleData, 9); +#else + CHKSIZE(ModuleData, 6); +#endif CHKSIZE(GVarData, 7); CHKSIZE(RssiAlarmData, 2); CHKSIZE(TrainerData, 16); -#if defined(PCBXLITE) - CHKSIZE(RadioData, 844); - CHKSIZE(ModelData, 6025); +#if defined(PCBXLITES) + CHKSIZE(RadioData, 858); + CHKSIZE(ModelData, 5940); +#elif defined(PCBXLITE) + CHKSIZE(RadioData, 852); + CHKSIZE(ModelData, 5940); #elif defined(PCBX7) - CHKSIZE(RadioData, 850); - CHKSIZE(ModelData, 6025); + CHKSIZE(RadioData, 858); + CHKSIZE(ModelData, 5940); #elif defined(PCBX9E) - CHKSIZE(RadioData, 952); - CHKSIZE(ModelData, 6520); + CHKSIZE(RadioData, 960); + CHKSIZE(ModelData, 6435); #elif defined(PCBX9D) - CHKSIZE(RadioData, 872); - CHKSIZE(ModelData, 6507); + CHKSIZE(RadioData, 880); + CHKSIZE(ModelData, 6422); #elif defined(PCBSKY9X) - CHKSIZE(RadioData, 727); - CHKSIZE(ModelData, 5188); + CHKSIZE(RadioData, 735); + CHKSIZE(ModelData, 5101); #elif defined(PCBHORUS) - CHKSIZE(RadioData, 847); - CHKSIZE(ModelData, 9380); + CHKSIZE(RadioData, 855); + CHKSIZE(ModelData, 9771); #endif #undef CHKSIZE diff --git a/radio/src/definitions.h b/radio/src/definitions.h index e921389f9..8b5f5391e 100644 --- a/radio/src/definitions.h +++ b/radio/src/definitions.h @@ -22,6 +22,8 @@ #define _DEFINITIONS_H_ #include +#include +#include #if !defined(UNUSED) #define UNUSED(x) ((void)(x)) /* to avoid warnings */ diff --git a/radio/src/fifo.h b/radio/src/fifo.h index e24b9ba80..a61d31839 100644 --- a/radio/src/fifo.h +++ b/radio/src/fifo.h @@ -21,6 +21,8 @@ #ifndef _FIFO_H_ #define _FIFO_H_ +#include + template class Fifo { @@ -40,13 +42,18 @@ class Fifo void push(T element) { - uint32_t next = (widx+1) & (N-1); + uint32_t next = nextIndex(widx); if (next != ridx) { fifo[widx] = element; widx = next; } } + void skip() + { + ridx = nextIndex(ridx); + } + bool pop(T & element) { if (isEmpty()) { @@ -54,7 +61,7 @@ class Fifo } else { element = fifo[ridx]; - ridx = (ridx+1) & (N-1); + ridx = nextIndex(ridx); return true; } } @@ -66,7 +73,7 @@ class Fifo bool isFull() { - uint32_t next = (widx+1) & (N-1); + uint32_t next = nextIndex(widx); return (next == ridx); } @@ -77,7 +84,7 @@ class Fifo uint32_t size() const { - return (N + widx - ridx) & (N-1); + return (N + widx - ridx) & (N - 1); } uint32_t hasSpace(uint32_t n) const @@ -100,6 +107,11 @@ class Fifo T fifo[N]; volatile uint32_t widx; volatile uint32_t ridx; + + inline uint32_t nextIndex(uint32_t idx) + { + return (idx + 1) & (N - 1); + } }; #endif // _FIFO_H_ diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index 5142df59c..ef286f494 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -155,8 +155,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext active &= (bool)CFN_ACTIVE(cfn); } - if (active || IS_PLAY_BOTH_FUNC(CFN_FUNC(cfn))) { - + if (active) { switch (CFN_FUNC(cfn)) { #if defined(OVERRIDE_CHANNEL_FUNCTION) @@ -233,7 +232,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext { unsigned int moduleIndex = CFN_PARAM(cfn); if (moduleIndex < NUM_MODULES) { - moduleFlag[moduleIndex] = 1 + CFN_FUNC(cfn) - FUNC_RANGECHECK; + moduleSettings[moduleIndex].mode = 1 + CFN_FUNC(cfn) - FUNC_RANGECHECK; } break; } @@ -404,7 +403,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext { unsigned int moduleIndex = CFN_PARAM(cfn); if (moduleIndex < NUM_MODULES) { - moduleFlag[moduleIndex] = 0; + moduleSettings[moduleIndex].mode = 0; } break; } diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index 6b814dd46..f557fba48 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -27,7 +27,7 @@ #define MENUS_SCROLLBAR_WIDTH 0 -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) #define HEADER_LINE 0 #define HEADER_LINE_COLUMNS #else @@ -40,7 +40,6 @@ #define NUM_BODY_LINES (LCD_LINES-1) #define MENU_HEADER_HEIGHT FH -#define MENU_INIT_VPOS 0 #define CURVE_SIDE_WIDTH (LCD_H/2) #define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2) @@ -53,45 +52,32 @@ extern uint8_t noHighlightCounter; #define NO_HIGHLIGHT() (noHighlightCounter > 0) #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) - void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); -#if defined(NAVIGATION_POT1) -extern int16_t p1valdiff; -#else - #define p1valdiff 0 -#endif - -#if defined(NAVIGATION_POT2) -extern int8_t p2valdiff; -#else - #define p2valdiff 0 -#endif - extern int8_t checkIncDec_Ret; // global helper vars -#define EDIT_SELECT_MENU -1 #define EDIT_SELECT_FIELD 0 #define EDIT_MODIFY_FIELD 1 #define EDIT_MODIFY_STRING 2 extern int8_t s_editMode; // global editmode // checkIncDec flags -#define EE_GENERAL 0x01 -#define EE_MODEL 0x02 + +// we leave room for EE_MODEL and EE_GENERAL #define NO_INCDEC_MARKS 0x04 #define INCDEC_SWITCH 0x08 #define INCDEC_SOURCE 0x10 #define INCDEC_REP10 0x40 #define NO_DBLKEYS 0x80 - #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL - #define INCDEC_SET_FLAG(f) incdecFlag = (f) - #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn - #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) +#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL +#define INCDEC_SET_FLAG(f) incdecFlag = (f) +#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn +#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) // mawrow special values -#define TITLE_ROW ((uint8_t)-1) +#define READONLY_ROW ((uint8_t)-1) +#define TITLE_ROW READONLY_ROW #define HIDDEN_ROW ((uint8_t)-2) struct CheckIncDecStops { @@ -167,9 +153,9 @@ void check_submenu_simple(event_t event, uint8_t maxrow); void title(const char * s); #define TITLE(str) title(str) - #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__ +#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__ -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) #define MENU_CHECK(tab, menu, lines_count) \ check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count) #else @@ -182,13 +168,12 @@ void title(const char * s); MENU_CHECK(tab, menu, lines_count); \ TITLE(title) -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) #define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \ check_simple(event, menu, tab, DIM(tab), lines_count); -#define SUBMENU_NOTITLE(lines_count, ...) { \ +#define SUBMENU_NOTITLE(lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \ - } + check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); #define SUBMENU(title, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \ @@ -198,10 +183,9 @@ void title(const char * s); #else #define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \ check_simple(event, menu, tab, DIM(tab), (lines_count)-1); -#define SUBMENU_NOTITLE(lines_count, ...) { \ +#define SUBMENU_NOTITLE(lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \ - } + check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); #define SUBMENU(title, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ @@ -211,8 +195,6 @@ void title(const char * s); #define SIMPLE_SUBMENU_NOTITLE(lines_count) \ check_submenu_simple(event, (lines_count)-1); - - #endif #define SIMPLE_MENU(title, tab, menu, lines_count) \ @@ -232,32 +214,21 @@ int8_t editSwitch(coord_t x, coord_t y, int8_t value, LcdFlags attr, event_t eve #define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event) #if defined(GVARS) - #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event) -#else - #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event) -#endif - -#if defined(GVARS) +#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event) int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event); void drawGVarName(coord_t x, coord_t y, int8_t index, LcdFlags flags=0); void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags=0); void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags); -#elif defined(GVARS) -int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event); +#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) #else int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event); +#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event) +#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) #endif void gvarWeightItem(coord_t x, coord_t y, MixData * md, LcdFlags attr, event_t event); -#if defined(GVARS) -#define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) -#else -#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) -#endif - void editName(coord_t x, coord_t y, char * name, uint8_t size, event_t event, uint8_t active, LcdFlags attr=ZCHAR); - void editSingleName(coord_t x, coord_t y, const char * label, char * name, uint8_t size, event_t event, uint8_t active); uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay); @@ -265,13 +236,7 @@ uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint #define WARNING_TYPE_ASTERISK 0 #define WARNING_TYPE_CONFIRM 1 -#define WARNING_TYPE_INPUT 2 - -extern const char * warningText; -extern const char * warningInfoText; -extern uint8_t warningInfoLength; -extern uint8_t warningResult; -extern uint8_t warningType; +#define WARNING_TYPE_INFO 2 #define COPY_MODE 1 #define MOVE_MODE 2 @@ -295,11 +260,11 @@ void drawStatusLine(); #endif #define TEXT_FILENAME_MAXLEN 40 - extern char s_text_file[TEXT_FILENAME_MAXLEN]; - void menuTextView(event_t event); - void pushMenuTextView(const char *filename); - void pushModelNotes(); - void readModelNotes(); +extern char s_text_file[TEXT_FILENAME_MAXLEN]; +void menuTextView(event_t event); +void pushMenuTextView(const char *filename); +void pushModelNotes(); +void readModelNotes(); #define LABEL(...) (uint8_t)-1 @@ -335,7 +300,7 @@ void drawStatusLine(); #endif // TODO enum -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) #define EDIT_MODE_INIT 0 #else #define EDIT_MODE_INIT -1 @@ -357,8 +322,6 @@ void onSourceLongEnterPress(const char *result); uint8_t switchToMix(uint8_t source); -void deleteExpoMix(uint8_t expo, uint8_t idx); - void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); extern const unsigned char sticks[] ; @@ -370,15 +333,12 @@ void drawStick(coord_t centrex, int16_t xval, int16_t yval); void drawPotsBars(); void doMainScreenGraphics(); -void drawProgressBar(const char * label, int num, int den); +void drawProgressScreen(const char * title, const char * message, int num, int den); void drawSleepBitmap(); void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); -#if defined(PCBTARANIS) void drawAlertBox(const char * title, const char * text, const char * action); -#endif - void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound); #define SET_SCROLLBAR_X(x) diff --git a/radio/src/gui/128x64/lcd.cpp b/radio/src/gui/128x64/lcd.cpp index fa1cd058c..d800521df 100644 --- a/radio/src/gui/128x64/lcd.cpp +++ b/radio/src/gui/128x64/lcd.cpp @@ -292,7 +292,7 @@ uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags) { uint8_t width = 0; for (int i=0; len==0 || i9 ? c+'A'-10 : c+'0'; + lcdDrawChar(x, y, c, flags|(c>='A' ? CONDENSED : 0)); + val >>= 4; + } +} + + void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val) { lcdDrawNumber(x, y, val); diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h index c1a562130..3eb08e861 100644 --- a/radio/src/gui/128x64/lcd.h +++ b/radio/src/gui/128x64/lcd.h @@ -124,7 +124,8 @@ void lcdDrawTextAlignedLeft(coord_t y, const char * s); #define lcdDrawTextAlignedCenter(y, s) lcdDrawText((LCD_W-sizeof(TR_##s)*FW+FW+1)/2, y, STR_##s) - void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0); +void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0); +void lcdDrawHexChar(coord_t x, coord_t y, uint8_t val, LcdFlags flags=0); void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags mode, uint8_t len); void lcdDrawNumber(coord_t x, coord_t y, lcdint_t val, LcdFlags mode=0); diff --git a/radio/src/gui/128x64/menus.cpp b/radio/src/gui/128x64/menus.cpp index e153fda4e..e09448460 100644 --- a/radio/src/gui/128x64/menus.cpp +++ b/radio/src/gui/128x64/menus.cpp @@ -33,6 +33,13 @@ void popMenu() TRACE("popMenu(%d)", menuLevel); } +void abortPopMenu() +{ + menuLevel = menuLevel + 1; + menuEvent = 0; + TRACE("popMenu(%d) aborted", menuLevel); +} + void chainMenu(MenuHandlerFunc newMenu) { menuHandlers[menuLevel] = newMenu; diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index ee5c9e552..26e9af134 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -56,6 +56,17 @@ extern uint8_t menuEvent; void chainMenu(MenuHandlerFunc newMenu); void pushMenu(MenuHandlerFunc newMenu); void popMenu(); +void abortPopMenu(); + +inline bool isRadioMenuDisplayed() +{ + return menuVerticalPositions[0] == 1; +} + +inline bool isModelMenuDisplayed() +{ + return menuVerticalPositions[0] == 0; +} inline MenuHandlerFunc lastPopMenu() { @@ -63,7 +74,6 @@ inline MenuHandlerFunc lastPopMenu() } void onMainViewMenu(const char * result); - void menuFirstCalib(event_t event); void menuMainView(event_t event); void menuViewTelemetryFrsky(event_t event); @@ -73,10 +83,11 @@ enum MenuRadioIndexes { MENU_RADIO_SETUP, CASE_SDCARD(MENU_RADIO_SD_MANAGER) + MENU_RADIO_TOOLS, MENU_RADIO_SPECIAL_FUNCTIONS, MENU_RADIO_TRAINER, - MENU_RADIO_VERSION, MENU_RADIO_HARDWARE, + MENU_RADIO_VERSION, MENU_RADIO_PAGES_COUNT }; @@ -88,15 +99,19 @@ void menuRadioVersion(event_t event); void menuRadioDiagKeys(event_t event); void menuRadioDiagAnalogs(event_t event); void menuRadioHardware(event_t event); +void menuRadioTools(event_t event); +void menuRadioSpectrumAnalyser(event_t event); +void menuRadioPowerMeter(event_t event); void menuRadioCalibration(event_t event); static const MenuHandlerFunc menuTabGeneral[] = { menuRadioSetup, CASE_SDCARD(menuRadioSdManager) + menuRadioTools, menuRadioSpecialFunctions, menuRadioTrainer, - menuRadioVersion, - menuRadioHardware + menuRadioHardware, + menuRadioVersion }; enum MenuModelIndexes { @@ -120,6 +135,9 @@ enum MenuModelIndexes { void menuModelSelect(event_t event); void menuModelSetup(event_t event); +void menuModelFailsafe(event_t event); +void menuModelModuleOptions(event_t event); +void menuModelReceiverOptions(event_t event); void menuModelHeli(event_t event); void menuModelFlightModesAll(event_t event); void menuModelExpoOne(event_t event); diff --git a/radio/src/gui/128x64/model_curve_edit.cpp b/radio/src/gui/128x64/model_curve_edit.cpp index 3a0112109..188f4c868 100644 --- a/radio/src/gui/128x64/model_curve_edit.cpp +++ b/radio/src/gui/128x64/model_curve_edit.cpp @@ -20,17 +20,39 @@ #include "opentx.h" -void displayPresetChoice(event_t event) +void runPopupCurvePreset(event_t event) { - runPopupWarning(event); - lcdDrawNumber(WARNING_LINE_X+FW*7, WARNING_LINE_Y, 45*warningInputValue/4, LEFT|INVERS); + warningResult = false; + + drawMessageBox(warningText); + + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+2*FH, STR_POPUPS_ENTER_EXIT); + + switch (event) { + case EVT_KEY_BREAK(KEY_ENTER): + warningResult = true; + // no break + + case EVT_KEY_BREAK(KEY_EXIT): + warningText = NULL; + warningType = WARNING_TYPE_ASTERISK; + break; + + default: + s_editMode = EDIT_MODIFY_FIELD; + reusableBuffer.curveEdit.preset = checkIncDec(event, reusableBuffer.curveEdit.preset, -4, 4); + s_editMode = EDIT_SELECT_FIELD; + break; + } + + lcdDrawNumber(WARNING_LINE_X+FW*7, WARNING_LINE_Y, 45 * reusableBuffer.curveEdit.preset / 4, LEFT|INVERS); lcdDrawChar(lcdLastRightPos, WARNING_LINE_Y, '@', INVERS); if (warningResult) { warningResult = 0; CurveInfo & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); - int k = 25 * warningInputValue; + int k = 25 * reusableBuffer.curveEdit.preset; int dx = 2000 / (5+crv.points-1); for (uint8_t i=0; i<5+crv.points; i++) { int x = -1000 + i * dx; @@ -45,7 +67,8 @@ void displayPresetChoice(event_t event) void onCurveOneMenu(const char * result) { if (result == STR_CURVE_PRESET) { - POPUP_INPUT(STR_PRESET, displayPresetChoice, 0, -4, 4); + reusableBuffer.curveEdit.preset = 4; // 45° + POPUP_INPUT(STR_PRESET, runPopupCurvePreset); } else if (result == STR_MIRROR) { CurveInfo & crv = g_model.curves[s_curveChan]; diff --git a/radio/src/gui/128x64/model_custom_scripts.cpp b/radio/src/gui/128x64/model_custom_scripts.cpp index e63e57e5f..4ff56e735 100644 --- a/radio/src/gui/128x64/model_custom_scripts.cpp +++ b/radio/src/gui/128x64/model_custom_scripts.cpp @@ -37,7 +37,7 @@ void onModelCustomScriptMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a lua file in the list copySelection(sd.file, result, sizeof(sd.file)); memset(sd.inputs, 0, sizeof(sd.inputs)); diff --git a/radio/src/gui/128x64/model_display.cpp b/radio/src/gui/128x64/model_display.cpp index cc8db7a72..03cd4c094 100644 --- a/radio/src/gui/128x64/model_display.cpp +++ b/radio/src/gui/128x64/model_display.cpp @@ -73,7 +73,7 @@ void onTelemetryScriptFileSelectionMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file)); storageDirty(EE_MODEL); diff --git a/radio/src/gui/128x64/model_failsafe.cpp b/radio/src/gui/128x64/model_failsafe.cpp new file mode 100644 index 000000000..2896e8c95 --- /dev/null +++ b/radio/src/gui/128x64/model_failsafe.cpp @@ -0,0 +1,138 @@ +/* + * 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. + */ + +#include + +extern uint8_t g_moduleIdx; + +void menuModelFailsafe(event_t event) +{ + const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + uint8_t wbar = LCD_W - FW * 4 - FWNUM * 4; +#if defined(PPM_UNIT_PERCENT_PREC1) + wbar -= 6; +#endif + + if (event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + event = 0; + + if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { + if (s_editMode > 0) { + g_model.failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; + s_editMode = 0; + } + else { + int16_t & failsafe = g_model.failsafeChannels[menuVerticalPosition]; + if (failsafe < FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_HOLD; + else if (failsafe == FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_NOPULSE; + else + failsafe = 0; + } + } + else { + // "Outputs => Failsafe" menu item + setCustomFailsafe(g_moduleIdx); + } + + storageDirty(EE_MODEL); + AUDIO_WARNING1(); + SEND_FAILSAFE_NOW(g_moduleIdx); + } + + SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1); + + lcdDrawTextAlignedCenter(0, FAILSAFESET); + lcdInvertLine(0); + + const coord_t x = 1; + coord_t y = FH + 1; + uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); + uint8_t ch = (menuVerticalPosition >= 8 ? 8 : 0) + line; + + // Channels + for (; line < 8; line++) { + const int32_t channelValue = channelOutputs[ch+channelStart]; + int32_t failsafeValue = g_model.failsafeChannels[ch]; + + // Channel + putsChn(x+1, y, ch+1, SMLSIZE); + + // Value + LcdFlags flags = TINSIZE; + if (menuVerticalPosition == ch) { + flags |= INVERS; + if (s_editMode > 0) { + if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + s_editMode = 0; + } + else { + flags |= BLINK; + CHECK_INCDEC_MODELVAR(event, g_model.failsafeChannels[ch], -lim, +lim); + } + } + } + + const coord_t xValue = x+LCD_W-4-wbar; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); + failsafeValue = 0; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); + failsafeValue = 0; + } + else { +#if defined(PPM_UNIT_US) + lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); +#elif defined(PPM_UNIT_PERCENT_PREC1) + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); +#else + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); +#endif + } + + // Gauge +#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines + lcdDrawRect(x+LCD_W-3-wbar, y, wbar+1, 6); +#endif + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2); + const uint8_t lenFailsafe = limit(1, (abs(failsafeValue) * wbar/2 + lim/2) / lim, wbar/2); + const coord_t xChannel = (channelValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenChannel; + const coord_t xFailsafe = (failsafeValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenFailsafe; + lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); + lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); + lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); + lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); + + y += FH - 1; + + if (++ch >= sentModuleChannels(g_moduleIdx)) + break; + } + + if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { + // Outputs => Failsafe + lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); + } +} diff --git a/radio/src/gui/128x64/model_flightmodes.cpp b/radio/src/gui/128x64/model_flightmodes.cpp index f6f46800b..a9dd6fa4a 100644 --- a/radio/src/gui/128x64/model_flightmodes.cpp +++ b/radio/src/gui/128x64/model_flightmodes.cpp @@ -39,7 +39,7 @@ enum MenuModelFlightModeItems { IF_ROTARY_ENCODERS(ITEM_MODEL_FLIGHT_MODE_ROTARY_ENCODERS) ITEM_MODEL_FLIGHT_MODE_FADE_IN, ITEM_MODEL_FLIGHT_MODE_FADE_OUT, -#if defined(GVARS) && !defined(PCBSTD) +#if defined(GVARS) ITEM_MODEL_FLIGHT_MODE_GVARS_LABEL, ITEM_MODEL_FLIGHT_MODE_GV1, ITEM_MODEL_FLIGHT_MODE_GV2, @@ -87,7 +87,7 @@ void menuModelFlightModeOne(event_t event) int8_t sub = menuVerticalPosition; int8_t editMode = s_editMode; -#if defined(GVARS) && !defined(PCBSTD) +#if defined(GVARS) if (s_currIdx == 0 && sub>=ITEM_MODEL_FLIGHT_MODE_SWITCH) sub += VERTICAL_SHIFT; for (uint8_t k=0; k0) || p1valdiff)) { + if (attr && menuHorizontalPosition == t && editMode > 0) { int16_t v = flightModeAddress(s_currIdx)->rotaryEncoders[t]; if (v < ROTARY_ENCODER_MAX) v = ROTARY_ENCODER_MAX; v = checkIncDec(event, v, ROTARY_ENCODER_MAX, ROTARY_ENCODER_MAX+MAX_FLIGHT_MODES-1, EE_MODEL); @@ -147,7 +147,7 @@ void menuModelFlightModeOne(event_t event) fm->fadeOut = EDIT_DELAY(0, y, event, attr, STR_FADEOUT, fm->fadeOut); break; -#if defined(GVARS) && !defined(PCBSTD) +#if defined(GVARS) case ITEM_MODEL_FLIGHT_MODE_GVARS_LABEL: lcdDrawTextAlignedLeft(y, STR_GLOBAL_VARS); break; @@ -175,7 +175,7 @@ void menuModelFlightModeOne(event_t event) else { lcdDrawText(9*FW, y, STR_OWN, posHorz==1 ? attr : 0); } - if (attr && s_currIdx>0 && posHorz==1 && (editMode>0 || p1valdiff)) { + if (attr && s_currIdx>0 && posHorz==1 && editMode > 0) { if (v < GVAR_MAX) v = GVAR_MAX; v = checkIncDec(event, v, GVAR_MAX, GVAR_MAX+MAX_FLIGHT_MODES-1, EE_MODEL); if (checkIncDec_Ret) { diff --git a/radio/src/gui/128x64/model_inputs_mixes.cpp b/radio/src/gui/128x64/model_inputs_mixes.cpp index 6535b8821..c35954d9d 100644 --- a/radio/src/gui/128x64/model_inputs_mixes.cpp +++ b/radio/src/gui/128x64/model_inputs_mixes.cpp @@ -524,7 +524,6 @@ void menuModelMixOne(event_t event) #define MIX_LINE_SWITCH_POS 16*FW #define MIX_LINE_DELAY_POS 19*FW+7 -#if defined(NAVIGATION_MENUS) void onExpoMixMenu(const char *result) { bool expo = (menuHandlers[menuLevel] == menuModelExposAll); @@ -551,7 +550,6 @@ void onExpoMixMenu(const char *result) deleteExpoMix(expo, s_currIdx); } } -#endif void displayMixInfos(coord_t y, MixData *md) { @@ -672,7 +670,6 @@ void menuModelExpoMix(uint8_t expo, event_t event) } else { if (s_copyMode) s_currCh = 0; -#if defined(NAVIGATION_MENUS) if (s_currCh) { if (reachExpoMixCountLimit(expo)) break; insertExpoMix(expo, s_currIdx); @@ -691,15 +688,6 @@ void menuModelExpoMix(uint8_t expo, event_t event) POPUP_MENU_ADD_ITEM(STR_DELETE); POPUP_MENU_START(onExpoMixMenu); } -#else - if (s_currCh) { - if (reachExpoMixCountLimit(expo)) break; - insertExpoMix(expo, s_currIdx); - } - pushMenu(expo ? menuModelExpoOne : menuModelMixOne); - s_copyMode = 0; - return; -#endif } } break; diff --git a/radio/src/gui/128x64/model_logical_switches.cpp b/radio/src/gui/128x64/model_logical_switches.cpp index 0d2303bfe..d8cf78c47 100644 --- a/radio/src/gui/128x64/model_logical_switches.cpp +++ b/radio/src/gui/128x64/model_logical_switches.cpp @@ -234,8 +234,7 @@ void onLogicalSwitchesMenu(const char *result) s_currIdx = sub; pushMenu(menuModelLogicalSwitchOne); } - - if (result == STR_COPY) { + else if (result == STR_COPY) { clipboard.type = CLIPBOARD_TYPE_CUSTOM_SWITCH; clipboard.data.csw = *cs; } @@ -269,8 +268,8 @@ void menuModelLogicalSwitches(event_t event) POPUP_MENU_ADD_ITEM(STR_PASTE); if (cs->func || cs->v1 || cs->v2 || cs->delay || cs->duration || cs->andsw) POPUP_MENU_ADD_ITEM(STR_CLEAR); - if(popupMenuNoItems == 1) { - popupMenuNoItems = 0; + if(popupMenuItemsCount == 1) { + popupMenuItemsCount = 0; s_currIdx = sub; pushMenu(menuModelLogicalSwitchOne); } diff --git a/radio/src/gui/128x64/model_module_options.cpp b/radio/src/gui/128x64/model_module_options.cpp new file mode 100644 index 000000000..cc2dec0af --- /dev/null +++ b/radio/src/gui/128x64/model_module_options.cpp @@ -0,0 +1,215 @@ +/* + * 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. + */ + +#include +#include + +#define RECEIVER_OPTIONS_2ND_COLUMN (11*FW) + +extern uint8_t g_moduleIdx; + +void onTxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = 2; + reusableBuffer.hardwareAndSettings.moduleSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; + } + else { + popMenu(); + } +} + +enum { + ITEM_MODULE_SETTINGS_RF_PROTOCOL, + ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, + ITEM_MODULE_SETTINGS_POWER, + ITEM_MODULE_SETTINGS_COUNT +}; + +/* Options order: + * - RF Protocol + * - External antenna + * - Power + */ +const uint8_t moduleOptions[] = { + 0b11111111, // None = display all options + 0b11111011, // XJT + 0b11111011, // IXJT + 0b11111011, // IXJT-PRO + 0b11111011, // IXJT-S + 0b11111100, // R9M + 0b11111100, // R9MLite + 0b11111100, // R9MLite-PRO +}; + +#define IF_MODULE_OPTIONS(option, count) uint8_t((moduleOptions[modelId] & (1 << option)) ? count : HIDDEN_ROW) + +void drawPower(coord_t x, coord_t y, int8_t dBm) +{ + float power_W_PREC1 = pow(10.0, (dBm - 30.0) / 10.0) * 10; + if (dBm >= 30) { + lcdDrawNumber(x, y, power_W_PREC1, PREC1); + lcdDrawText(lcdNextPos, y, "W"); + } + else if (dBm < 10) { + uint16_t power_MW_PREC1 = round(power_W_PREC1 * 1000); + lcdDrawNumber(x, y, power_MW_PREC1, PREC1); + lcdDrawText(lcdNextPos, y, "mW"); + } + else { + uint16_t power_MW = round(power_W_PREC1 * 100); + if (power_MW >= 50) { + power_MW = (power_MW / 5) * 5; + lcdDrawNumber(x, y, power_MW); + lcdDrawText(lcdNextPos, y, "mW"); + } + else { + lcdDrawNumber(x, y, power_MW); + lcdDrawText(lcdNextPos, y, "mW"); + } + } +} + +bool isPowerAvailable(int value) +{ +// uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; +// uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + + return (value == 10 /* 10 mW */ || + value == 14 /* 25 mW */ || + value == 20 /* 100 mW */ || + value == 23 /* 200 mW */ || + value == 27 /* 500 mW */ || + value == 30 /* 1000 mW */); +} + +void menuModelModuleOptions(event_t event) +{ + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; + // uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + + SUBMENU_NOTITLE(ITEM_MODULE_SETTINGS_COUNT, { + IF_MODULE_OPTIONS(0, 0), + IF_MODULE_OPTIONS(1, 0), + IF_MODULE_OPTIONS(2, 0), + }); + + if (event == EVT_ENTRY) { +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; +#else + // no need to initialize reusableBuffer.hardwareAndSettings.moduleSettings.state to PXX2_HARDWARE_INFO + reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].current = PXX2_HW_INFO_TX_ID; + reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].maximum = PXX2_HW_INFO_TX_ID; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_GET_HARDWARE_INFO; +#endif + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_HARDWARE_INFO && moduleSettings[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_READ; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; + } + + if (menuEvent) { + moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION("Update TX options?", onTxOptionsUpdateConfirm); + } + else { + return; + } + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = 0; + reusableBuffer.hardwareAndSettings.moduleSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + } + + if (modelId != 0 && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + menuVerticalPosition = 0; + while (menuVerticalPosition < ITEM_MODULE_SETTINGS_COUNT && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + ++menuVerticalPosition; + } + } + + int8_t sub = menuVerticalPosition; + lcdDrawTextAlignedLeft(0, "Module options"); + lcdInvertLine(0); + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_MODULE_SETTINGS_RF_PROTOCOL: + lcdDrawText(0, y, "RF Protocol"); + lcdDrawTextAtIndex(RECEIVER_OPTIONS_2ND_COLUMN, y, STR_XJT_PROTOCOLS, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol + 1, attr); + if (attr) { + reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, 0, nullptr); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + } + break; + + case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: + reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, "Ext. antenna", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + break; + + case ITEM_MODULE_SETTINGS_POWER: + lcdDrawText(0, y, "Power"); + lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, attr); + lcdDrawText(lcdNextPos, y, "dBm("); + drawPower(lcdNextPos, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower); + lcdDrawText(lcdNextPos, y, ")"); + if (attr) { + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, 0, 30, 0, &isPowerAvailable); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + } + break; + } + } + } + else { + lcdDrawText(4 * FW, 4 * FH, "Waiting for TX..."); + } +} diff --git a/radio/src/gui/128x64/model_outputs_arm.cpp b/radio/src/gui/128x64/model_outputs_arm.cpp index e3e27b387..2e1437240 100644 --- a/radio/src/gui/128x64/model_outputs_arm.cpp +++ b/radio/src/gui/128x64/model_outputs_arm.cpp @@ -113,7 +113,7 @@ void menuModelLimitsOne(event_t event) coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH; uint8_t i = k + menuVerticalOffset; uint8_t attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); - uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; + uint8_t active = (attr && s_editMode > 0) ; int limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 1000); switch (i) { diff --git a/radio/src/gui/128x64/model_receiver_options.cpp b/radio/src/gui/128x64/model_receiver_options.cpp new file mode 100644 index 000000000..24cddfe01 --- /dev/null +++ b/radio/src/gui/128x64/model_receiver_options.cpp @@ -0,0 +1,157 @@ +/* + * 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. + */ + +#include + +#define RECEIVER_OPTIONS_2ND_COLUMN 80 + +extern uint8_t g_moduleIdx; +extern void drawReceiverName(uint8_t x, uint8_t y, uint8_t receiverSlot); + +void onRxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 2; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + else { + popMenu(); + } +} + +enum { + ITEM_RECEIVER_TELEMETRY, + ITEM_RECEIVER_PWM_RATE, + ITEM_RECEIVER_PINMAP_FIRST +}; + +void menuModelReceiverOptions(event_t event) +{ + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + uint8_t wbar = LCD_W / 2 - 20; + auto outputsCount = min(16, reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount); + + SIMPLE_SUBMENU_NOTITLE(ITEM_RECEIVER_PINMAP_FIRST + outputsCount); + + if (event == EVT_ENTRY) { +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount = 8; +#else + // no need to initialize reusableBuffer.hardwareAndSettings.receiverSettings.state to PXX2_HARDWARE_INFO + reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].current = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId; + reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].maximum = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_GET_HARDWARE_INFO; +#endif + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_HARDWARE_INFO && moduleSettings[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_READ; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + + if (menuEvent) { + moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION("Update RX options?", onRxOptionsUpdateConfirm); + } + else { + return; + } + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 0; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + return; + } + + int8_t sub = menuVerticalPosition; + lcdDrawTextAlignedLeft(0, STR_RECEIVER_OPTIONS); + drawReceiverName(FW * 13, 0, reusableBuffer.hardwareAndSettings.receiverSettings.receiverId); + lcdInvertLine(0); + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_RECEIVER_TELEMETRY: + reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled, RECEIVER_OPTIONS_2ND_COLUMN, y, "Telem. disabled", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + break; + + case ITEM_RECEIVER_PWM_RATE: + reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate, RECEIVER_OPTIONS_2ND_COLUMN, y, "9ms PWM", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + break; + + default: + // Pin + { + uint8_t pin = i - ITEM_RECEIVER_PINMAP_FIRST; + uint8_t channel = reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin]; + int32_t channelValue = channelOutputs[channel]; + lcdDrawText(0, y, "Pin"); + lcdDrawNumber(lcdLastRightPos + 1, y, pin + 1); + putsChn(7 * FW, y, channel + 1, attr); + + // Channel + if (attr) { + channel = checkIncDec(event, channel, 0, sentModuleChannels(g_moduleIdx) - 1); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin] = channel; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + } + + // Bargraph +#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines + lcdDrawRect(LCD_W - 3 - wbar, y + 1, wbar + 1, 4); +#endif + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar / 2 + lim / 2) / lim, wbar / 2); + const coord_t xChannel = (channelValue > 0) ? LCD_W - 3 - wbar / 2 : LCD_W - 2 - wbar / 2 - lenChannel; + lcdDrawHorizontalLine(xChannel, y + 2, lenChannel, SOLID, 0); + lcdDrawHorizontalLine(xChannel, y + 3, lenChannel, SOLID, 0); + break; + } + } + } + } + else { + lcdDrawText(4 * FW, 4 * FH, "Waiting for RX..."); + } +} diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp index e91a3a53b..8b7aa6b33 100644 --- a/radio/src/gui/128x64/model_select.cpp +++ b/radio/src/gui/128x64/model_select.cpp @@ -22,7 +22,6 @@ #define MODELSEL_W LCD_W -#if defined(NAVIGATION_MENUS) void onModelSelectMenu(const char * result) { int8_t sub = menuVerticalPosition; @@ -53,11 +52,11 @@ void onModelSelectMenu(const char * result) } #endif else if (result == STR_DELETE_MODEL) { - POPUP_CONFIRMATION(STR_DELETEMODEL); + POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); } #if defined(SDCARD) - else { + else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); POPUP_WARNING(eeRestoreModel(sub, (char *)result)); @@ -67,7 +66,6 @@ void onModelSelectMenu(const char * result) } #endif } -#endif void menuModelSelect(event_t event) { @@ -89,12 +87,6 @@ void menuModelSelect(event_t event) check_submenu_simple(_event_, MAX_MODELS - HEADER_LINE); -#if defined(NAVIGATION_POT2) - if (event==0 && p2valdiff<0) { - event = EVT_KEY_FIRST(KEY_RIGHT); - } -#endif - if (s_editMode > 0) s_editMode = 0; @@ -112,7 +104,7 @@ void menuModelSelect(event_t event) case EVT_KEY_LONG(KEY_EXIT): killEvents(event); if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { - POPUP_CONFIRMATION(STR_DELETEMODEL); + POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); } else { @@ -200,7 +192,6 @@ void menuModelSelect(event_t event) else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) { s_copyMode = 0; killEvents(event); -#if defined(NAVIGATION_MENUS) if (g_eeGeneral.currModel != sub) { if (eeModelExists(sub)) { POPUP_MENU_ADD_ITEM(STR_SELECT_MODEL); @@ -224,11 +215,6 @@ void menuModelSelect(event_t event) POPUP_MENU_ADD_ITEM(STR_MOVE_MODEL); } POPUP_MENU_START(onModelSelectMenu); -#else - if (g_eeGeneral.currModel != sub) { - selectModel(sub); - } -#endif } else if (eeModelExists(sub)) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); @@ -237,7 +223,7 @@ void menuModelSelect(event_t event) } break; -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) case EVT_KEY_LONG(KEY_PAGE): chainMenu(menuTabModel[DIM(menuTabModel)-1]); killEvents(event); @@ -269,7 +255,7 @@ void menuModelSelect(event_t event) #endif #endif -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) case EVT_ROTARY_LEFT: case EVT_ROTARY_RIGHT: #endif @@ -310,7 +296,7 @@ void menuModelSelect(event_t event) lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, RIGHT); #endif -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), 0); #elif defined(ROTARY_ENCODER_NAVIGATION) drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_ROTARY_ENCODER_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0); diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 6b2298f09..e26dd2cc9 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -18,10 +18,25 @@ * GNU General Public License for more details. */ -#include "opentx.h" +#include +// TODO find why we need this (for REGISTER at least) +#if defined(PCBXLITE) + #define EVT_BUTTON_PRESSED() EVT_KEY_FIRST(KEY_ENTER) +#else + #define EVT_BUTTON_PRESSED() EVT_KEY_BREAK(KEY_ENTER) +#endif + +// TODO can be moved to reusableBuffer uint8_t g_moduleIdx; -void menuModelFailsafe(event_t event); + +void drawReceiverName(uint8_t x, uint8_t y, uint8_t receiverSlot) +{ + if (g_model.receiverData[receiverSlot].name[0] != '\0') + lcdDrawSizedText(x, y, g_model.receiverData[receiverSlot].name, PXX2_LEN_RX_NAME); + else + lcdDrawText(x, y, "---"); +} #if defined(PCBTARANIS) uint8_t getSwitchWarningsCount() @@ -70,15 +85,28 @@ enum MenuModelSetupItems { #endif ITEM_MODEL_BEEP_CENTER, ITEM_MODEL_USE_GLOBAL_FUNCTIONS, + ITEM_MODEL_REGISTRATION_ID, #if defined(PCBTARANIS) ITEM_MODEL_INTERNAL_MODULE_LABEL, ITEM_MODEL_INTERNAL_MODULE_MODE, ITEM_MODEL_INTERNAL_MODULE_CHANNELS, - ITEM_MODEL_INTERNAL_MODULE_BIND, - ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, -#if defined(PCBXLITE) + ITEM_MODEL_INTERNAL_MODULE_NPXX2_BIND, + ITEM_MODEL_INTERNAL_MODULE_PXX2_MODEL_NUM, +#if defined(EXTERNAL_ANTENNA) ITEM_MODEL_INTERNAL_MODULE_ANTENNA, #endif + ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_INTERNAL_MODULE_PXX2_REGISTER_RANGE, + ITEM_MODEL_INTERNAL_MODULE_PXX2_OPTIONS, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_LABEL, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_LABEL, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS, + ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE, #endif ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_MODE, @@ -88,7 +116,8 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_SYNCSTATUS, #endif ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, - ITEM_MODEL_EXTERNAL_MODULE_BIND, + ITEM_MODEL_EXTERNAL_MODULE_NPXX2_BIND, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_MODEL_NUM, #if defined(PCBSKY9X) && defined(REVX) ITEM_MODEL_EXTERNAL_MODULE_OUTPUT_TYPE, #endif @@ -97,18 +126,32 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, +#if !defined(PCBXLITE) + ITEM_MODEL_EXTERNAL_MODULE_FREQ, +#endif + ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_REGISTER_RANGE, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_OPTIONS, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_LABEL, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS, + ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE, #if defined(PCBSKY9X) && !defined(REVA) ITEM_MODEL_EXTRA_MODULE_LABEL, ITEM_MODEL_EXTRA_MODULE_CHANNELS, ITEM_MODEL_EXTRA_MODULE_BIND, #endif - ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, -#if defined(BLUETOOTH) - ITEM_MODEL_TRAINER_BLUETOOTH, -#endif + #if defined(BLUETOOTH) + ITEM_MODEL_TRAINER_BLUETOOTH, + #endif ITEM_MODEL_TRAINER_CHANNELS, ITEM_MODEL_TRAINER_PARAMS, #elif defined(PCBXLITE) @@ -116,6 +159,7 @@ enum MenuModelSetupItems { ITEM_MODEL_TRAINER_MODE, ITEM_MODEL_TRAINER_BLUETOOTH, ITEM_MODEL_TRAINER_CHANNELS, + ITEM_MODEL_TRAINER_PARAMS, #endif ITEM_MODEL_SETUP_MAX }; @@ -131,10 +175,15 @@ enum MenuModelSetupItems { #define MODEL_SETUP_RANGE_OFS 4*FW+3 #define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2 +#define IF_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? (uint8_t)(xxx) : HIDDEN_ROW) +#define IF_NOT_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? HIDDEN_ROW : (uint8_t)(xxx)) +#define IF_PXX2_RECEIVER_DISPLAYED(module, idx, xxx) ((isModulePXX2(module) && g_model.moduleData[module].pxx2.getReceiverSlot(idx)) ? (uint8_t)(xxx) : HIDDEN_ROW) + #if defined(PCBTARANIS) - #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) + #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) + #define CURRENT_RECEIVER_EDITED(k) ((k - (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL : ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) / (ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL - ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) #elif defined(PCBSKY9X) && !defined(REVA) - #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE) + #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE) #else #define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE) #endif @@ -144,59 +193,89 @@ enum MenuModelSetupItems { #else #define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 5 ? TITLE_ROW : HIDDEN_ROW) #endif -#if !defined(TARANIS_INTERNAL_PPM) - #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) -#else + +#if defined(TARANIS_INTERNAL_PPM) #define INTERNAL_MODULE_MODE_ROWS (isModuleXJT(INTERNAL_MODULE) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols +#else + #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) #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) - #define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1) - #define EXTERNAL_MODULE_BIND_ROWS() ((isModuleXJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(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_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) +#define EXTERNAL_MODULE_BIND_ROWS() ((isModuleXJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW #if defined(PCBSKY9X) && defined(REVX) #define OUTPUT_TYPE_ROWS() (isModulePPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW) , #else #define OUTPUT_TYPE_ROWS() #endif - #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) +#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) + +#if defined(PCBXLITE) #define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 + #define EXTERNAL_MODULE_FREQ_ROW +#else + #define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 + #define EXTERNAL_MODULE_FREQ_ROW isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, +#endif + +#define CURSOR_ON_CELL (true) +#define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX) +#define POT_WARN_ITEMS() ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) +#define TIMER_ROWS 2, 0, 0, 0, 0 - #define CURSOR_ON_CELL (true) - #define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX) - #define POT_WARN_ITEMS() ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) - #define TIMER_ROWS 2, 0, 0, 0, 0 #if defined(PCBSKY9X) && !defined(REVA) #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, #else #define EXTRA_MODULE_ROWS #endif -#if defined(PCBX7) -#define ANTENNA_ROW -#if defined(BLUETOOTH) - #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) - #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) - #define TRAINER_BLUETOOTH_ROW (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)), -#else - #define TRAINER_BLUETOOTH_ROW -#endif -#define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) -#define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) -#define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW -#elif defined(PCBXLITE) - #define ANTENNA_ROW IF_INTERNAL_MODULE_ON(0), +#if defined(PCBX7) || defined(PCBX3) + #define ANTENNA_ROW + #if defined(BLUETOOTH) + #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) + #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) + #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)), + #else + #define TRAINER_BLUETOOTH_ROW + #endif + #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) + #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW +#elif defined(PCBXLITES) + #define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), #define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW) #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) - #define TRAINER_BLUETOOTH_ROW (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)) + #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)) + #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) + #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_ROWS LABEL(Trainer), 0, IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW +#elif defined(PCBXLITE) + #define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), + #define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW) + #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) + #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) + #define TRAINER_BLUETOOTH_ROW (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)) #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) #define TRAINER_ROWS IF_BT_TRAINER_ON(LABEL(Trainer)), IF_BT_TRAINER_ON(0), IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), IF_BT_TRAINER_ON(TRAINER_CHANNELS_ROW) #else #define TRAINER_ROWS #endif +void onPXX2BindMenu(const char * result) +{ + if (result != STR_EXIT) { + reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex = (result - reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]) / sizeof(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]); + reusableBuffer.moduleSetup.pxx2.bindStep = BIND_RX_NAME_SELECTED; + } + else { + // the user pressed [Exit] + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition); + moduleSettings[moduleIdx].mode = MODULE_MODE_NORMAL; + } +} void onBindMenu(const char * result) { @@ -222,13 +301,116 @@ void onBindMenu(const char * result) return; } - moduleFlag[moduleIdx] = MODULE_BIND; + moduleSettings[moduleIdx].mode = MODULE_MODE_BIND; } +enum PopupRegisterItems { + ITEM_REGISTER_PASSWORD, + ITEM_REGISTER_MODULE_INDEX, + ITEM_REGISTER_RECEIVER_NAME, + ITEM_REGISTER_BUTTONS +}; + +void runPopupRegister(event_t event) +{ + uint8_t backupVerticalPosition = menuVerticalPosition; + uint8_t backupHorizontalPosition = menuHorizontalPosition; + uint8_t backupVerticalOffset = menuVerticalOffset; + int8_t backupEditMode = s_editMode; + + menuVerticalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition; + menuHorizontalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition; + s_editMode = reusableBuffer.moduleSetup.pxx2.registerPopupEditMode; + + switch (event) { + case EVT_KEY_BREAK(KEY_ENTER): + if (menuVerticalPosition != ITEM_REGISTER_BUTTONS) { + break; + } + else if (reusableBuffer.moduleSetup.pxx2.registerStep >= REGISTER_RX_NAME_RECEIVED && menuHorizontalPosition == 0) { + // [Enter] pressed + reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; + backupEditMode = EDIT_MODIFY_FIELD; // so that the [Register] button blinks and the REGISTER process can continue + } + // no break + + case EVT_KEY_LONG(KEY_EXIT): + s_editMode = 0; + // no break; + + case EVT_KEY_BREAK(KEY_EXIT): + if (s_editMode <= 0) { + warningText = nullptr; + } + break; + } + + if (warningText) { + const uint8_t dialogRows[] = { 0, 0, uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? READONLY_ROW : 0), uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? 0 : 1)}; + check(event, 0, nullptr, 0, dialogRows, 3, 4 - HEADER_LINE); // TODO add a comment for 3 - HEADER_LINE once understood + + drawMessageBox(warningText); + + // registration password + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4, STR_REG_ID); + editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4, g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID, event, menuVerticalPosition == ITEM_REGISTER_PASSWORD); + + // module index + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + FH, "UID"); + lcdDrawNumber(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + FH, reusableBuffer.moduleSetup.pxx2.registerModuleIndex, menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX ? (s_editMode ? INVERS + BLINK : INVERS) : 0); + if (menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX && s_editMode) { + CHECK_INCDEC_MODELVAR_ZERO(event, reusableBuffer.moduleSetup.pxx2.registerModuleIndex, 7); + } + + // RX name + if (reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED) { + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, "Waiting ..."); + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS ? INVERS : 0); + } + else { + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, STR_RX_NAME); + editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + 2 * FH, reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME, event, menuVerticalPosition == ITEM_REGISTER_RECEIVER_NAME); + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_ENTER, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 0 ? INVERS : 0); + lcdDrawText(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 1 ? INVERS : 0); + } + + reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition = menuVerticalPosition; + reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition = menuHorizontalPosition; + reusableBuffer.moduleSetup.pxx2.registerPopupEditMode = s_editMode; + } + + menuVerticalPosition = backupVerticalPosition; + menuHorizontalPosition = backupHorizontalPosition; + menuVerticalOffset = backupVerticalOffset; + s_editMode = backupEditMode; +} + +void startRegisterDialog(uint8_t module) +{ + memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); + moduleSettings[module].mode = MODULE_MODE_REGISTER; + s_editMode = 0; + POPUP_INPUT("", runPopupRegister); +} + +inline bool isDefaultModelRegistrationID() +{ + return memcmp(g_model.modelRegistrationID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID) == 0; +} + +uint8_t findEmptyReceiverSlot() +{ + for (uint8_t slot=0; slot 1 - moduleFlag[1] = 0; + moduleSettings[1].mode = 0; #endif } #endif @@ -307,7 +524,7 @@ void menuModelSetup(event_t event) TITLE(STR_MENUSETUP); if (event == EVT_ENTRY) { - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; } uint8_t sub = menuVerticalPosition - HEADER_LINE; @@ -342,7 +559,7 @@ void menuModelSetup(event_t event) drawStringWithIndex(0*FW, y, STR_TIMER, timerIdx+1); drawTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0); drawTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, RIGHT | (menuHorizontalPosition==1 ? attr : 0), menuHorizontalPosition==2 ? attr : 0); - if (attr && (editMode>0 || p1valdiff)) { + if (attr && editMode > 0) { div_t qr = div(timer->start, 60); switch (menuHorizontalPosition) { case 0: @@ -542,7 +759,7 @@ void menuModelSetup(event_t event) for (int i=0; i= NUM_SWITCHES)) { lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), 1+FH*((current+4)/5)); } -#else //PCBTARANIS +#else // PCBTARANIS { lcdDrawTextAlignedLeft(y, STR_SWITCHWARNING); swarnstate_t states = g_model.switchWarningState; @@ -616,6 +833,7 @@ void menuModelSetup(event_t event) #endif break; } + #if defined(PCBTARANIS) case ITEM_MODEL_POTS_WARNING: lcdDrawTextAlignedLeft(y, STR_POTWARNING); @@ -673,7 +891,7 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: - g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable); - if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); - if (isModuleSBUS(EXTERNAL_MODULE)) - g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; - if(isModulePPM(EXTERNAL_MODULE)) - SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE); + { + uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, + MODULE_TYPE_NONE, + IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : + MODULE_TYPE_COUNT - 1, EE_MODEL, + isExternalModuleAvailable); + if (checkIncDec_Ret) { + // TODO this code should be common, in module.h (X10_new_UI branch) + memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData)); + g_model.moduleData[EXTERNAL_MODULE].type = moduleType; + g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); + if (isModuleSBUS(EXTERNAL_MODULE)) + g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; + if (isModulePPM(EXTERNAL_MODULE)) + SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE); + } } break; case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); +#if defined(PCBXLITE) else if (isModuleR9M(EXTERNAL_MODULE)) { uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { @@ -764,7 +994,7 @@ void menuModelSetup(event_t event) } g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; } - +#endif #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -811,7 +1041,7 @@ void menuModelSetup(event_t event) if (pdef->subTypeString != nullptr) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, attr); } - if (attr && (editMode > 0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: if (multi_rfProto == MM_RF_CUSTOM_SELECTED) @@ -836,9 +1066,9 @@ void menuModelSetup(event_t event) case ITEM_MODEL_TRAINER_MODE: lcdDrawTextAlignedLeft(y, STR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, attr); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr); if (attr) { - g_model.trainerMode = checkIncDec(event, g_model.trainerMode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable); + g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable); #if defined(BLUETOOTH) if (checkIncDec_Ret) { bluetoothState = BLUETOOTH_STATE_OFF; @@ -851,7 +1081,7 @@ void menuModelSetup(event_t event) #if defined(PCBTARANIS) && defined(BLUETOOTH) case ITEM_MODEL_TRAINER_BLUETOOTH: - if (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH) { + if (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH) { if (attr) { s_editMode = 0; } @@ -900,6 +1130,25 @@ void menuModelSetup(event_t event) #if defined(PCBTARANIS) case ITEM_MODEL_TRAINER_CHANNELS: + lcdDrawTextAlignedLeft(y, STR_CHANNELRANGE); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); + lcdDrawNumber(lcdLastRightPos, y, g_model.trainerData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); + lcdDrawChar(lcdLastRightPos, y, '-'); + lcdDrawNumber(lcdLastRightPos + FW+1, y, g_model.trainerData.channelsStart + 8 + g_model.trainerData.channelsCount, LEFT | (menuHorizontalPosition==1 ? attr : 0)); + if (attr && editMode > 0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.trainerData.channelsStart, 32-8-g_model.trainerData.channelsCount); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.channelsCount, -4, min(MAX_TRAINER_CHANNELS_M8, 32-8-g_model.trainerData.channelsStart)); + break; + } + } + break; +#endif + +#if defined(PCBTARANIS) case ITEM_MODEL_INTERNAL_MODULE_CHANNELS: #endif #if defined(PCBSKY9X) @@ -915,13 +1164,13 @@ void menuModelSetup(event_t event) 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)); - if (attr && (editMode>0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); break; case 1: - CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart)); + CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_XJT2 ? isPXX2ChannelsCountAllowed : nullptr); if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM)) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); } @@ -932,16 +1181,213 @@ void menuModelSetup(event_t event) break; } -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) case ITEM_MODEL_TRAINER_PARAMS: + lcdDrawTextAlignedLeft(y, STR_PPMFRAME); + lcdDrawText(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.trainerData.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); + lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.trainerData.delay*50)+300, RIGHT | ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0)); + lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.trainerData.pulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0); + if (attr && editMode > 0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.frameLength, -20, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.delay, -4, 10); + break; + case 2: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.trainerData.pulsePol, 1); + break; + } + } + break; #endif + #if defined(PCBTARANIS) - case ITEM_MODEL_INTERNAL_MODULE_BIND: + case ITEM_MODEL_REGISTRATION_ID: + lcdDrawTextAlignedLeft(y, STR_REG_ID); + if (isDefaultModelRegistrationID()) + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, ""); + else + lcdDrawSizedText(MODEL_SETUP_2ND_COLUMN, y, g_model.modelRegistrationID, sizeof(g_model.modelRegistrationID), ZCHAR); + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_MODEL_NUM: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_MODEL_NUM: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_RECEIVER_NUM); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], attr | LEADING0 | LEFT, 2); + if (attr) { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], MAX_RX_NUM(moduleIdx)); + if (checkIncDec_Ret) { + modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx]; + } + } + } + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_REGISTER_RANGE: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_REGISTER_RANGE: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_MODULE); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_REGISTER_BUTTON, (menuHorizontalPosition == 0 ? attr : 0)); + lcdDrawText(lcdLastRightPos + 3, y, STR_MODULE_RANGE, (menuHorizontalPosition == 1 ? attr : 0)); + if (attr) { + if (moduleSettings[moduleIdx].mode == MODULE_MODE_NORMAL && s_editMode > 0) { + if (menuHorizontalPosition == 0 && event == EVT_BUTTON_PRESSED()) { + startRegisterDialog(moduleIdx); + } + else if (menuHorizontalPosition == 1) { + moduleSettings[moduleIdx].mode = MODULE_MODE_RANGECHECK; + } + } + if (s_editMode == 0 && !warningText) { + moduleSettings[moduleIdx].mode = MODULE_MODE_NORMAL; + } + if (moduleSettings[moduleIdx].mode == MODULE_MODE_NORMAL) { + // REGISTER finished + s_editMode = 0; + } + } + } + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_LABEL: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_LABEL: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_LABEL: + { + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + uint8_t receiverSlot = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx); + + lcdDrawTextAlignedLeft(y, STR_RECEIVER); + lcdDrawNumber(lcdLastRightPos + 1, y, receiverIdx + 1); + + if (receiverSlot) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DEL_BUTTON, attr); + if (attr && s_editMode > 0) { + g_model.moduleData[moduleIdx].pxx2.receivers = (g_model.moduleData[moduleIdx].pxx2.receivers & BF_MASK(0, receiverIdx * 3)) | ((g_model.moduleData[moduleIdx].pxx2.receivers & BF_MASK((receiverIdx + 1) * 3, (MAX_RECEIVERS_PER_MODULE - 1 - receiverIdx) * 3)) >> 3); + memclear(&g_model.receiverData[receiverSlot - 1], sizeof(ReceiverData)); + s_editMode = 0; + killEvents(event); + storageDirty(EE_MODEL); + } + } + else { + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_RXADD_BUTTON, attr); + if (attr && s_editMode > 0) { + s_editMode = 0; + killEvents(event); + uint8_t slot = findEmptyReceiverSlot(); + if (slot > 0) { + g_model.moduleData[moduleIdx].pxx2.receivers |= (slot << (receiverIdx * 3)); + --slot; + g_model.receiverData[slot].used = 1; + storageDirty(EE_MODEL); + } + } + } + } + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_OPTIONS: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_OPTIONS: + lcdDrawText(INDENT_WIDTH, y, STR_OPTIONS); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); + if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { + g_moduleIdx = CURRENT_MODULE_EDITED(k); + memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); + pushMenu(menuModelModuleOptions); + } + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_OPTIONS: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_OPTIONS: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_OPTIONS: + lcdDrawText(INDENT_WIDTH * 2, y, STR_OPTIONS); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); + if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { + g_moduleIdx = CURRENT_MODULE_EDITED(k); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); + uint8_t receiverSlot = g_model.moduleData[g_moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1; + memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); + reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverSlot; + pushMenu(menuModelReceiverOptions); + } + break; + + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE: + case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE: + case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); + uint8_t receiverSlot = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1; + + drawReceiverName(INDENT_WIDTH * 2, y, receiverSlot); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, menuHorizontalPosition==0 ? attr : 0); + lcdDrawText(lcdLastRightPos + FW/2, y, STR_BUTTON_SHARE, menuHorizontalPosition==1 ? attr : 0); + + if (attr) { + if (menuHorizontalPosition == 0) { + if (event == EVT_KEY_BREAK(KEY_ENTER)) { + // TODO this will go to module.cpp + memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); + reusableBuffer.moduleSetup.pxx2.bindReceiverId = receiverSlot; + moduleSettings[moduleIdx].mode ^= MODULE_MODE_BIND; + } + else if (event == EVT_KEY_BREAK(KEY_EXIT)) { + moduleSettings[moduleIdx].mode &= ~MODULE_MODE_BIND; + } + if (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND) { + s_editMode = 1; + if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_START && reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount > 0) { + popupMenuItemsCount = min(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); + for (uint8_t i=0; i0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -20, 35); @@ -998,7 +1444,7 @@ void menuModelSetup(event_t event) if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2); if (attr && l_posHorz == 0) { - if (editMode>0 || p1valdiff) { + if (editMode > 0) { CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], MAX_RX_NUM(moduleIdx)); if (checkIncDec_Ret) { modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx]; @@ -1058,36 +1504,36 @@ void menuModelSetup(event_t event) POPUP_MENU_START(onBindMenu); continue; } - if (moduleFlag[moduleIdx] == MODULE_BIND) { - newFlag = MODULE_BIND; + if (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND) { + newFlag = MODULE_MODE_BIND; } else { - if (!popupMenuNoItems) { + if (!popupMenuItemsCount) { s_editMode = 0; // this is when popup is exited before a choice is made } } } else { - newFlag = MODULE_BIND; + newFlag = MODULE_MODE_BIND; } } else if (l_posHorz == 2) { - newFlag = MODULE_RANGECHECK; + newFlag = MODULE_MODE_RANGECHECK; } } } #else if (attr && l_posHorz>0 && s_editMode>0) { if (l_posHorz == 1) - newFlag = MODULE_BIND; + newFlag = MODULE_MODE_BIND; else if (l_posHorz == 2) - newFlag = MODULE_RANGECHECK; + newFlag = MODULE_MODE_RANGECHECK; } #endif - moduleFlag[moduleIdx] = newFlag; + moduleSettings[moduleIdx].mode = newFlag; #if defined(MULTIMODULE) - if (newFlag == MODULE_BIND) { + if (newFlag == MODULE_MODE_BIND) { multiBindStatus = MULTI_BIND_INITIATED; } #endif @@ -1121,11 +1567,12 @@ void menuModelSetup(event_t event) if (moduleData.failsafeMode != FAILSAFE_CUSTOM) menuHorizontalPosition = 0; if (menuHorizontalPosition == 0) { - if (editMode > 0 || p1valdiff) { + if (editMode > 0) { CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.failsafeMode, FAILSAFE_LAST); if (checkIncDec_Ret) SEND_FAILSAFE_NOW(moduleIdx); } - } else if (menuHorizontalPosition == 1) { + } + else if (menuHorizontalPosition == 1) { s_editMode = 0; if (moduleData.failsafeMode == FAILSAFE_CUSTOM) { if (event == EVT_KEY_LONG(KEY_ENTER)) { @@ -1135,12 +1582,13 @@ void menuModelSetup(event_t event) AUDIO_WARNING1(); SEND_FAILSAFE_NOW(moduleIdx); } - else if (event == EVT_KEY_BREAK(KEY_ENTER)) { + else if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { g_moduleIdx = moduleIdx; pushMenu(menuModelFailsafe); } } - } else { + } + else { lcdDrawSolidFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W - MODEL_SETUP_2ND_COLUMN, 8); } } @@ -1152,7 +1600,7 @@ void menuModelSetup(event_t event) { uint8_t newAntennaSel = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_ANTENNASELECTION, STR_VANTENNATYPES, g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna, 0, 1, attr, event); if (newAntennaSel != g_model.moduleData[INTERNAL_MODULE].pxx.external_antenna && newAntennaSel == XJT_EXTERNAL_ANTENNA) { - POPUP_CONFIRMATION(STR_ANTENNACONFIRM1); + POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, nullptr); const char * w = STR_ANTENNACONFIRM2; SET_WARNING_INFO(w, strlen(w), 0); } @@ -1191,6 +1639,7 @@ void menuModelSetup(event_t event) } } #endif +#if defined(PCBXLITE) if (isModuleR9M(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY); if (IS_TELEMETRY_INTERNAL_MODULE()) { @@ -1201,6 +1650,9 @@ void menuModelSetup(event_t event) } } else if (isModuleSBUS(moduleIdx)) { +#else + if (isModuleSBUS(moduleIdx)) { +#endif lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); } @@ -1230,11 +1682,11 @@ void menuModelSetup(event_t event) if (attr) { CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].pxx.power, R9M_LBT_POWER_MAX); } - if (attr && editMode == 0 && reusableBuffer.modelsetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { - if((reusableBuffer.modelsetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) { //switching between mode 2 and 3 does not require rebind + if (attr && editMode == 0 && reusableBuffer.moduleSetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { + if((reusableBuffer.moduleSetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) { //switching between mode 2 and 3 does not require rebind POPUP_WARNING(STR_REBIND); } - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; } } } @@ -1247,6 +1699,20 @@ void menuModelSetup(event_t event) } break; +#if !defined(PCBXLITE) + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); + } + } + break; +#endif + #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) @@ -1283,7 +1749,7 @@ void menuModelSetup(event_t event) lcdDrawNumber(lcdLastRightPos, y, g_model.moduleData[1].channelsStart+1, LEFT | (menuHorizontalPosition<=0 ? attr : 0)); lcdDrawChar(lcdLastRightPos, y, '-'); lcdDrawNumber(lcdLastRightPos + FW+1, y, g_model.moduleData[1].channelsStart+8+g_model.moduleData[1].channelsCount, LEFT | (menuHorizontalPosition!=0 ? attr : 0)); - if (attr && (editMode>0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[1].channelsStart, 32-8-g_model.moduleData[1].channelsCount); @@ -1304,7 +1770,7 @@ void menuModelSetup(event_t event) lcdDrawChar(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (g_model.moduleData[1].ppmDelay*50)+300, RIGHT | ((menuHorizontalPosition < 0 || menuHorizontalPosition==1) ? attr : 0)); lcdDrawChar(MODEL_SETUP_2ND_COLUMN+10*FW, y, g_model.moduleData[1].ppmPulsePol ? '+' : '-', (menuHorizontalPosition < 0 || menuHorizontalPosition==2) ? attr : 0); - if (attr && (editMode>0 || p1valdiff)) { + if (attr && editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, g_model.moduleData[1].ppmFrameLength, -20, 35); @@ -1326,7 +1792,7 @@ void menuModelSetup(event_t event) #if defined(PXX) if (IS_RANGECHECK_ENABLE()) { showMessageBox("RSSI: "); - lcdDrawNumber(16+4*FW, 5*FH, TELEMETRY_RSSI(), BOLD); + lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD); } #endif @@ -1334,7 +1800,7 @@ void menuModelSetup(event_t event) if (old_editMode > 0 && s_editMode == 0) { switch(menuVerticalPosition) { #if defined(PCBTARANIS) - case ITEM_MODEL_INTERNAL_MODULE_BIND: + case ITEM_MODEL_INTERNAL_MODULE_NPXX2_BIND: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, INTERNAL_MODULE); break; @@ -1345,125 +1811,10 @@ void menuModelSetup(event_t event) checkModelIdUnique(g_eeGeneral.currModel, EXTRA_MODULE); break; #endif - case ITEM_MODEL_EXTERNAL_MODULE_BIND: + case ITEM_MODEL_EXTERNAL_MODULE_NPXX2_BIND: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE); break; } } } - -void menuModelFailsafe(event_t event) -{ - const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; - const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; - uint8_t wbar = LCD_W - FW * 4 - FWNUM * 4; -#if defined(PPM_UNIT_PERCENT_PREC1) - wbar -= 6; -#endif - - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - event = 0; - - if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { - if (s_editMode) { - g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; - s_editMode = 0; - } - else { - int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition]; - if (failsafe < FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_HOLD; - else if (failsafe == FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_NOPULSE; - else - failsafe = 0; - } - } - else { - // "Outputs => Failsafe" menu item - setCustomFailsafe(g_moduleIdx); - } - - storageDirty(EE_MODEL); - AUDIO_WARNING1(); - SEND_FAILSAFE_NOW(g_moduleIdx); - } - - SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1); - - lcdDrawTextAlignedCenter(0, FAILSAFESET); - lcdInvertLine(0); - - const coord_t x = 1; - coord_t y = FH + 1; - uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); - uint8_t ch = (menuVerticalPosition >= 8 ? 8 : 0) + line; - - // Channels - for (; line < 8; line++) { - const int32_t channelValue = channelOutputs[ch+channelStart]; - int32_t failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[ch]; - - //Channel - putsChn(x+1, y, ch+1, SMLSIZE); - - // Value - LcdFlags flags = TINSIZE; - if (menuVerticalPosition == ch) { - flags |= INVERS; - if (s_editMode) { - if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - s_editMode = 0; - } - else { - flags |= BLINK; - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[ch], -lim, +lim); - } - } - } - - uint8_t xValue = x+LCD_W-4-wbar; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); - failsafeValue = 0; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); - failsafeValue = 0; - } - else { -#if defined(PPM_UNIT_US) - lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); -#elif defined(PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); -#else - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); -#endif - } - - // Gauge -#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines - lcdDrawRect(x+LCD_W-3-wbar, y, wbar+1, 6); -#endif - const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2); - const uint8_t lenFailsafe = limit(1, (abs(failsafeValue) * wbar/2 + lim/2) / lim, wbar/2); - const coord_t xChannel = (channelValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenChannel; - const coord_t xFailsafe = (failsafeValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenFailsafe; - lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); - lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); - lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); - lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); - - y += FH - 1; - - if (++ch >= sentModuleChannels(g_moduleIdx)) - break; - } - - if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { - // Outputs => Failsafe - lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); - } -} diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index f8163d0a0..46f1b5d53 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -57,12 +57,12 @@ void onCustomFunctionsFileSelectionMenu(const char * result) strcpy(directory, SOUNDS_PATH); strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); } - if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), NULL)) { + if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), nullptr)) { POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); POPUP_MENU_UNSET_BSS_FLAG(); } } - else { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cfn->play.name, result, sizeof(cfn->play.name)); storageDirty(eeFlags); @@ -96,7 +96,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } @@ -186,7 +186,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF uint8_t func = CFN_FUNC(cfn); for (uint8_t j=0; j<5; j++) { uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); - uint8_t active = (attr && (s_editMode>0 || p1valdiff)); + uint8_t active = (attr && s_editMode > 0); switch (j) { case 0: if (sub==k && menuHorizontalPosition < 1 && CFN_SWITCH(cfn) == SWSRC_NONE) { @@ -390,7 +390,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF else if (attr) { REPEAT_LAST_CURSOR_MOVE(); } -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) if (active || event==EVT_KEY_LONG(KEY_ENTER)) { CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); if (func == FUNC_ADJUST_GVAR && attr && event==EVT_KEY_LONG(KEY_ENTER)) { @@ -409,7 +409,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF #else if (active) { CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); -#endif // PCBX7 +#endif } break; } @@ -437,7 +437,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF break; } } -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) if (sub==k && menuHorizontalPosition<0 && CFN_SWITCH(cfn)) { lcdInvertLine(i+1); } @@ -447,7 +447,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF void menuModelSpecialFunctions(event_t event) { -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) const CustomFunctionData * cfn = &g_model.customFn[menuVerticalPosition]; if (!CFN_SWITCH(cfn) && menuHorizontalPosition < 0 && event==EVT_KEY_BREAK(KEY_ENTER)) { menuHorizontalPosition = 0; @@ -457,7 +457,7 @@ void menuModelSpecialFunctions(event_t event) menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext); -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) if (!CFN_SWITCH(cfn) && menuHorizontalPosition == 0 && s_editMode <= 0) { menuHorizontalPosition = -1; } diff --git a/radio/src/gui/128x64/model_telemetry.cpp b/radio/src/gui/128x64/model_telemetry.cpp index 5e763fd5c..1231e3f37 100644 --- a/radio/src/gui/128x64/model_telemetry.cpp +++ b/radio/src/gui/128x64/model_telemetry.cpp @@ -423,7 +423,7 @@ void menuModelTelemetryFrsky(event_t event) switch (event) { case EVT_KEY_BREAK(KEY_DOWN): case EVT_KEY_BREAK(KEY_UP): -#if !defined(PCBX7) +#if !defined(PCBX7) && !defined(PCBX3) case EVT_KEY_BREAK(KEY_LEFT): case EVT_KEY_BREAK(KEY_RIGHT): #endif @@ -531,7 +531,7 @@ void menuModelTelemetryFrsky(event_t event) s_editMode = 0; if (event==EVT_KEY_LONG(KEY_ENTER)) { killEvents(KEY_ENTER); - POPUP_CONFIRMATION(STR_CONFIRMDELETE); + POPUP_CONFIRMATION(STR_CONFIRMDELETE, nullptr); } } break; @@ -543,7 +543,7 @@ void menuModelTelemetryFrsky(event_t event) case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) - if (telemetryProtocol == PROTOCOL_MULTIMODULE && + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FS_AFHDS2A) lcdDrawTextAlignedLeft(y, "RSNR"); else @@ -588,7 +588,7 @@ void menuModelTelemetryFrsky(event_t event) } lcdDrawNumber(TELEM_COL2, y, -10+g_model.frsky.varioMin, ((CURSOR_ON_LINE() || menuHorizontalPosition==0) ? attr : 0)|LEFT); lcdDrawNumber(TELEM_COL2+4*FW, y, 10+g_model.frsky.varioMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0)|LEFT); - if (attr && (s_editMode>0 || p1valdiff)) { + if (attr && s_editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMin, -7, 7); @@ -605,7 +605,7 @@ void menuModelTelemetryFrsky(event_t event) lcdDrawNumber(TELEM_COL2, y, -5+g_model.frsky.varioCenterMin, ((CURSOR_ON_LINE() || menuHorizontalPosition==0) ? attr : 0)|PREC1|LEFT); lcdDrawNumber(TELEM_COL2+4*FW, y, 5+g_model.frsky.varioCenterMax, ((CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0)|PREC1|LEFT); lcdDrawTextAtIndex(TELEM_COL2+8*FW, y, STR_VVARIOCENTER, g_model.frsky.varioCenterSilent, (menuHorizontalPosition==2 ? attr : 0)); - if (attr && (s_editMode>0 || p1valdiff)) { + if (attr && s_editMode > 0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMin, -16, 5+min(10, g_model.frsky.varioCenterMax+5)); diff --git a/radio/src/gui/128x64/model_templates.cpp b/radio/src/gui/128x64/model_templates.cpp index b03c24151..95693eb3e 100644 --- a/radio/src/gui/128x64/model_templates.cpp +++ b/radio/src/gui/128x64/model_templates.cpp @@ -33,7 +33,7 @@ void menuModelTemplates(event_t event) AUDIO_WARNING2(); } if (event==EVT_KEY_BREAK(KEY_ENTER)) { - POPUP_CONFIRMATION(STR_VTEMPLATES+1 + (sub * LEN2_VTEMPLATES)); + POPUP_CONFIRMATION(STR_VTEMPLATES+1 + (sub * LEN2_VTEMPLATES), nullptr); s_editMode = 0; } } diff --git a/radio/src/gui/128x64/popups.cpp b/radio/src/gui/128x64/popups.cpp index 25b9e28a3..977aa801c 100644 --- a/radio/src/gui/128x64/popups.cpp +++ b/radio/src/gui/128x64/popups.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -20,33 +20,6 @@ #include "opentx.h" -const char * warningText = NULL; -const char * warningInfoText; -uint8_t warningInfoLength; -uint8_t warningType; -uint8_t warningResult = 0; - -uint8_t warningInfoFlags = ZCHAR; -int16_t warningInputValue; -int16_t warningInputValueMin; -int16_t warningInputValueMax; - -void drawMessageBox() -{ - lcdDrawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE); - lcdDrawRect(10, 16, LCD_W-20, 40); - lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y, warningText, WARNING_LINE_LEN); - // could be a place for a warningInfoText -} - -void showMessageBox(const char * str) -{ - warningText = str; - drawMessageBox(); - warningText = NULL; - lcdRefresh(); -} - const unsigned char ASTERISK_BITMAP[] = { #include "asterisk.lbm" }; @@ -65,54 +38,16 @@ void drawAlertBox(const char * title, const char * text, const char * action) lcdDrawText(MESSAGE_LCD_OFFSET, 0, title, DBLSIZE); lcdDrawText(MESSAGE_LCD_OFFSET, 2*FH, STR_WARNING, DBLSIZE); #endif - + lcdDrawSolidFilledRect(0, 0, LCD_W, 32); + if (text) { lcdDrawTextAlignedLeft(5*FH, text); } + if (action) { lcdDrawTextAlignedLeft(7*FH, action); } - + #undef MESSAGE_LCD_OFFSET } - -void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound) -{ - drawAlertBox(title, text, action); - - AUDIO_ERROR_MESSAGE(sound); - - lcdRefresh(); - lcdSetContrast(); - clearKeyEvents(); - backlightOn(); - checkBacklight(); -} - -void runPopupWarning(event_t event) -{ - warningResult = false; - drawMessageBox(); - if (warningInfoText) { - lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+FH, warningInfoText, warningInfoLength, WARNING_INFO_FLAGS); - } - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+2*FH, warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS); - switch (event) { - case EVT_KEY_BREAK(KEY_ENTER): - if (warningType == WARNING_TYPE_ASTERISK) - break; - warningResult = true; - // no break - case EVT_KEY_BREAK(KEY_EXIT): - warningText = NULL; - warningType = WARNING_TYPE_ASTERISK; - break; - default: - if (warningType != WARNING_TYPE_INPUT) break; - s_editMode = EDIT_MODIFY_FIELD; - warningInputValue = checkIncDec(event, warningInputValue, warningInputValueMin, warningInputValueMax); - s_editMode = EDIT_SELECT_FIELD; - break; - } -} diff --git a/radio/src/gui/128x64/popups.h b/radio/src/gui/128x64/popups.h index bc413305e..73edb0a84 100644 --- a/radio/src/gui/128x64/popups.h +++ b/radio/src/gui/128x64/popups.h @@ -21,25 +21,20 @@ #ifndef _POPUPS_H_ #define _POPUPS_H_ -#define MENU_X 10 -#define MENU_Y 16 -#define MENU_W LCD_W-(2*MENU_X) +#include + +#define MESSAGEBOX_X 10 +#define MESSAGEBOX_Y 16 +#define MESSAGEBOX_W (LCD_W - 19) + +#define MENU_X MESSAGEBOX_X +#define MENU_Y MESSAGEBOX_Y +#define MENU_W MESSAGEBOX_W + #define WARNING_LINE_LEN 20 #define WARNING_LINE_X 16 #define WARNING_LINE_Y 3*FH -void drawMessageBox(); -void showMessageBox(const char * title); -void runPopupWarning(event_t event); - -#define DRAW_MESSAGE_BOX(title) (warningText = title, drawMessageBox(), warningText = NULL) - -extern void (*popupFunc)(event_t event); -extern int16_t warningInputValue; -extern int16_t warningInputValueMin; -extern int16_t warningInputValueMax; -extern uint8_t warningInfoFlags; - #if !defined(GUI) #define DISPLAY_WARNING(...) #define POPUP_WARNING(...) @@ -49,9 +44,10 @@ extern uint8_t warningInfoFlags; #define SET_WARNING_INFO(...) #else #define DISPLAY_WARNING (*popupFunc) + #define POPUP_INFORMATION(s) (warningText = s, warningType = WARNING_TYPE_INFO, warningInfoText = nullptr, popupFunc = runPopupWarning) #define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning) - #define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning) - #define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max) + #define POPUP_CONFIRMATION(s, func) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = nullptr, popupFunc = runPopupWarning, popupMenuHandler = func) + #define POPUP_INPUT(s, func) (warningText = s, popupFunc = func) #define WARNING_INFO_FLAGS warningInfoFlags #define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags) #endif @@ -62,28 +58,19 @@ extern uint8_t warningInfoFlags; #define POPUP_MENU_ADD_SD_ITEM(s) #endif - #define NAVIGATION_MENUS - #define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0) - #define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuNoItems ? s : popupMenuNoItems) : 0) - #define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0) - #define POPUP_MENU_MAX_LINES 12 - #define MENU_MAX_DISPLAY_LINES 6 - #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) - #define POPUP_MENU_SET_BSS_FLAG() - #define POPUP_MENU_UNSET_BSS_FLAG() - enum { - MENU_OFFSET_INTERNAL, - MENU_OFFSET_EXTERNAL - }; - extern uint8_t popupMenuOffsetType; - extern uint8_t s_menu_item; +#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuItemsCount++] = s; } while (0) +#define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuItemsCount ? s : popupMenuItemsCount) : 0) +#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0) +#define POPUP_MENU_MAX_LINES 12 +#define MENU_MAX_DISPLAY_LINES 6 +#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) +#define POPUP_MENU_SET_BSS_FLAG() +#define POPUP_MENU_UNSET_BSS_FLAG() +enum { + MENU_OFFSET_INTERNAL, + MENU_OFFSET_EXTERNAL +}; -#if defined(NAVIGATION_MENUS) - extern uint16_t popupMenuOffset; - extern const char * popupMenuItems[POPUP_MENU_MAX_LINES]; - extern uint16_t popupMenuNoItems; - const char * runPopupMenu(event_t event); - extern void (*popupMenuHandler)(const char * result); -#endif +#include "../common/stdlcd/popups.h" #endif // _POPUPS_H_ diff --git a/radio/src/gui/128x64/radio_diaganas.cpp b/radio/src/gui/128x64/radio_diaganas.cpp index 7665f7ca4..dc30519ac 100644 --- a/radio/src/gui/128x64/radio_diaganas.cpp +++ b/radio/src/gui/128x64/radio_diaganas.cpp @@ -67,48 +67,6 @@ void menuRadioDiagAnalogs(event_t event) } #endif - -#if defined(PCBTARANIS) - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH + 2, STR_BATT_CALIB); - putsVolts(LEN_CALIB_FIELDS*FW+FW, MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH + 2, getBatteryVoltage(), (menuVerticalPosition==HEADER_LINE ? INVERS | (s_editMode > 0 ? BLINK : 0) : 0) | PREC2 | LEFT); -#elif defined(PCBSKY9X) - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+4*FH, STR_BATT_CALIB); - static int32_t adcBatt; - // TODO board.cpp - adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8; - uint32_t batCalV = (adcBatt + adcBatt*(g_eeGeneral.txVoltageCalibration)/128) * 4191; - batCalV /= 55296; - putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+4*FH, batCalV, (menuVerticalPosition==HEADER_LINE ? INVERS : 0)); -#else - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH, STR_BATT_CALIB); - putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH, g_vbat100mV, (menuVerticalPosition==HEADER_LINE ? INVERS : 0)); -#endif - - if (menuVerticalPosition == HEADER_LINE) { - CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127); - } - -#if defined(TX_CAPACITY_MEASUREMENT) - lcdDrawTextAlignedLeft(6*FH+1, STR_CURRENT_CALIB); - drawValueWithUnit(LEN_CALIB_FIELDS*FW+4*FW, 6*FH+1, getCurrent(), UNIT_MILLIAMPS, (menuVerticalPosition==2 ? INVERS : 0)) ; - if (menuVerticalPosition==2) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txCurrentCalibration, -49, 49); -#endif - -#if defined(PCBSKY9X) - #if defined(TX_CAPACITY_MEASUREMENT) - #define TEMP_CALIB_POS 7*FH+1 - #define TEMP_CALIB_MENU_POS 3 - #else - #define TEMP_CALIB_POS 6*FH+1 - #define TEMP_CALIB_MENU_POS 2 - #endif - - lcdDrawTextAlignedLeft(TEMP_CALIB_POS, STR_TEMP_CALIB); - drawValueWithUnit(LEN_CALIB_FIELDS*FW+4*FW, TEMP_CALIB_POS, getTemperature(), UNIT_TEMPERATURE, (menuVerticalPosition==TEMP_CALIB_MENU_POS ? INVERS : 0)) ; - if (menuVerticalPosition==TEMP_CALIB_MENU_POS) - CHECK_INCDEC_GENVAR(event, g_eeGeneral.temperatureCalib, -100, 100); -#endif - #if (NUM_PWMSTICKS > 0) && !defined(SIMU) lcdDrawTextAlignedLeft(7*FH, STICKS_PWM_ENABLED() ? "Sticks: PWM" : "Sticks: ANA"); #endif diff --git a/radio/src/gui/128x64/radio_diagkeys.cpp b/radio/src/gui/128x64/radio_diagkeys.cpp index 35a3d73fa..214d14726 100644 --- a/radio/src/gui/128x64/radio_diagkeys.cpp +++ b/radio/src/gui/128x64/radio_diagkeys.cpp @@ -50,7 +50,7 @@ void menuRadioDiagKeys(event_t event) } if (i < TRM_BASE) { -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) y = MENU_HEADER_HEIGHT + FH + FH*i; if (i >= 2) { // hide PLUS and MINUS virtual buttons diff --git a/radio/src/gui/128x64/radio_hardware.cpp b/radio/src/gui/128x64/radio_hardware.cpp index 6025a9b6e..9203b40ea 100644 --- a/radio/src/gui/128x64/radio_hardware.cpp +++ b/radio/src/gui/128x64/radio_hardware.cpp @@ -103,17 +103,33 @@ enum MenuRadioHardwareItems { ITEM_RADIO_HARDWARE_STICK4, ITEM_RADIO_HARDWARE_LABEL_POTS, ITEM_RADIO_HARDWARE_POT1, +#if !defined(PCBX3) ITEM_RADIO_HARDWARE_POT2, +#endif ITEM_RADIO_HARDWARE_LABEL_SWITCHES, ITEM_RADIO_HARDWARE_SA, ITEM_RADIO_HARDWARE_SB, ITEM_RADIO_HARDWARE_SC, ITEM_RADIO_HARDWARE_SD, -#if NUM_SWITCHES > 4 +#if NUM_SWITCHES >= 5 ITEM_RADIO_HARDWARE_SF, +#endif +#if NUM_SWITCHES >= 6 ITEM_RADIO_HARDWARE_SH, #endif + ITEM_RADIO_HARDWARE_BATTERY_CALIB, +#if defined(STM32) + ITEM_RADIO_HARDWARE_RTC_BATTERY, +#endif +#if defined(TX_CAPACITY_MEASUREMENT) + ITEM_RADIO_HARDWARE_CAPACITY_CALIB, +#endif +#if defined(PCBSKY9X) + ITEM_RADIO_HARDWARE_TEMPERATURE_CALIB, +#endif +#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000 ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE, +#endif #if defined(BLUETOOTH) ITEM_RADIO_HARDWARE_BLUETOOTH_MODE, ITEM_RADIO_HARDWARE_BLUETOOTH_PAIRING_CODE, @@ -126,25 +142,38 @@ enum MenuRadioHardwareItems { ITEM_RADIO_HARDWARE_MAX }; -#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 - -#if NUM_SWITCHES > 4 -#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 +#if defined(PCBX3) +#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1 #else +#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 +#endif + +#if 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 +#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 +#elif NUM_SWITCHES == 4 #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #endif -#if defined(PCBTARANIS) -#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), +#if defined(PCBX3) + #define BLUETOOTH_ROWS +#elif defined(PCBTARANIS) + #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), #elif defined(BLUETOOTH) -#define BLUETOOTH_ROWS 0, 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 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), #else -#define BLUETOOTH_ROWS + #define BLUETOOTH_ROWS #endif -#if defined(PCBXLITE) -#define SWITCH_TYPE_MAX(sw) (SWITCH_3POS) + +#if defined(PCBX3) + #define SWITCH_TYPE_MAX(sw) (sw == MIXSRC_SD-MIXSRC_FIRST_SWITCH ? SWITCH_2POS : SWITCH_3POS) +#elif defined(PCBXLITES) + #define SWITCH_TYPE_MAX(sw) (sw >= MIXSRC_SE-MIXSRC_FIRST_SWITCH ? SWITCH_2POS : SWITCH_3POS) +#elif defined(PCBXLITE) + #define SWITCH_TYPE_MAX(sw) (SWITCH_3POS) #else -#define SWITCH_TYPE_MAX(sw) ((MIXSRC_SF-MIXSRC_FIRST_SWITCH == sw || MIXSRC_SH-MIXSRC_FIRST_SWITCH == sw) ? SWITCH_2POS : SWITCH_3POS) + #define SWITCH_TYPE_MAX(sw) ((MIXSRC_SF-MIXSRC_FIRST_SWITCH == sw || MIXSRC_SH-MIXSRC_FIRST_SWITCH == sw) ? SWITCH_2POS : SWITCH_3POS) #endif #define HW_SETTINGS_COLUMN1 30 @@ -152,16 +181,44 @@ enum MenuRadioHardwareItems { void menuRadioHardware(event_t event) { - MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, HEADER_LINE+ITEM_RADIO_HARDWARE_MAX, { HEADER_LINE_COLUMNS 0, 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, 0/*max bauds*/, BLUETOOTH_ROWS 0/*jitter filter*/, 1 /* debugs */ }); + MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, HEADER_LINE + ITEM_RADIO_HARDWARE_MAX, { + HEADER_LINE_COLUMNS + 0 /* calibration button */, + 0 /* stick 1 */, + 0 /* stick 2 */, + 0 /* stick 3 */, + 0 /* stick 4 */, + LABEL(Pots), + POTS_ROWS, + LABEL(Switches), + SWITCHES_ROWS, + 0 /* battery calib */, +#if defined(STM32) + READONLY_ROW, +#endif +#if defined(TX_CAPACITY_MEASUREMENT) + 0, +#endif +#if defined(PCBSKY9X) + 0, +#endif +#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000 + 0 /* max bauds */, +#endif + BLUETOOTH_ROWS + 0 /* jitter filter */, + 1 /* debugs */, + }); uint8_t sub = menuVerticalPosition - HEADER_LINE; - for (uint8_t i=0; i0) ? BLINK|INVERS : INVERS); uint8_t attr = (sub == k ? blink : 0); @@ -186,7 +243,9 @@ void menuRadioHardware(event_t event) break; case ITEM_RADIO_HARDWARE_POT1: +#if !defined(PCBX3) case ITEM_RADIO_HARDWARE_POT2: +#endif { int idx = k - ITEM_RADIO_HARDWARE_POT1; uint8_t shift = (2*idx); @@ -211,8 +270,10 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_HARDWARE_SB: case ITEM_RADIO_HARDWARE_SC: case ITEM_RADIO_HARDWARE_SD: -#if NUM_SWITCHES > 4 +#if NUM_SWITCHES >= 5 case ITEM_RADIO_HARDWARE_SF: +#endif +#if NUM_SWITCHES >= 6 case ITEM_RADIO_HARDWARE_SH: #endif { @@ -231,6 +292,55 @@ void menuRadioHardware(event_t event) break; } + case ITEM_RADIO_HARDWARE_BATTERY_CALIB: +#if defined(PCBTARANIS) + lcdDrawTextAlignedLeft(y, STR_BATT_CALIB); + putsVolts(HW_SETTINGS_COLUMN2, y, getBatteryVoltage(), attr|PREC2|LEFT); +#elif defined(PCBSKY9X) + lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+1+4*FH, STR_BATT_CALIB); + static int32_t adcBatt; + // TODO board.cpp + adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8; + uint32_t batCalV = (adcBatt + adcBatt*(g_eeGeneral.txVoltageCalibration)/128) * 4191; + batCalV /= 55296; + putsVolts(HW_SETTINGS_COLUMN2, y, batCalV, (menuVerticalPosition==HEADER_LINE ? INVERS : 0)); +#else + lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT + 1 + (NUM_STICKS+NUM_POTS+NUM_SLIDERS+1)/2 * FH, STR_BATT_CALIB); + putsVolts(HW_SETTINGS_COLUMN2, y, g_vbat100mV, attr|LEFT); +#endif + if (attr) { + CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127); + } + break; + +#if defined(STM32) + case ITEM_RADIO_HARDWARE_RTC_BATTERY: + lcdDrawTextAlignedLeft(y, "RTC Batt"); + putsVolts(HW_SETTINGS_COLUMN2, y, vbattRTC, PREC2|LEFT); + break; +#endif + +#if defined(TX_CAPACITY_MEASUREMENT) + case ITEM_RADIO_HARDWARE_CAPACITY_CALIB: + lcdDrawTextAlignedLeft(y, STR_CURRENT_CALIB); + drawValueWithUnit(HW_SETTINGS_COLUMN2, y, getCurrent(), UNIT_MILLIAMPS, attr); + if (attr) { + CHECK_INCDEC_GENVAR(event, g_eeGeneral.txCurrentCalibration, -49, 49); + } + break; +#endif + +#if defined(PCBSKY9X) + case ITEM_RADIO_HARDWARE_TEMPERATURE_CALIB: + lcdDrawTextAlignedLeft(y, STR_TEMP_CALIB); + drawValueWithUnit(HW_SETTINGS_COLUMN2, y, getTemperature(), UNIT_TEMPERATURE, attr) ; + if (attr) { + CHECK_INCDEC_GENVAR(event, g_eeGeneral.temperatureCalib, -100, 100); + } + break; +#endif + +#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000 case ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE: lcdDrawTextAlignedLeft(y, STR_MAXBAUDRATE); lcdDrawNumber(HW_SETTINGS_COLUMN2, y, CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate], attr|LEFT); @@ -248,6 +358,7 @@ void menuRadioHardware(event_t event) } } break; +#endif #if defined(BLUETOOTH) case ITEM_RADIO_HARDWARE_BLUETOOTH_MODE: @@ -289,7 +400,7 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_HARDWARE_DEBUG: lcdDrawTextAlignedLeft(y, STR_DEBUG); lcdDrawText(HW_SETTINGS_COLUMN2, y, STR_ANALOGS_BTN, menuHorizontalPosition == 0 ? attr : 0); - lcdDrawText(lcdLastRightPos + 2, y, STR_SWITCHES_BTN, menuHorizontalPosition == 1 ? attr : 0); + lcdDrawText(lcdLastRightPos + 2, y, STR_KEYS_BTN, menuHorizontalPosition == 1 ? attr : 0); if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { if (menuHorizontalPosition == 0) pushMenu(menuRadioDiagAnalogs); diff --git a/radio/src/gui/128x64/radio_setup.cpp b/radio/src/gui/128x64/radio_setup.cpp index ca8199462..2334fd44e 100644 --- a/radio/src/gui/128x64/radio_setup.cpp +++ b/radio/src/gui/128x64/radio_setup.cpp @@ -26,9 +26,9 @@ const unsigned char sticks[] = { #include "sticks.lbm" }; -#define RADIO_SETUP_2ND_COLUMN (LCD_W-6*FW-3) +#define RADIO_SETUP_2ND_COLUMN (LCD_W-7*FW-3) #define RADIO_SETUP_DATE_COLUMN (FW*15+7) -#define RADIO_SETUP_TIME_COLUMN (FW*15+9) +#define RADIO_SETUP_TIME_COLUMN (RADIO_SETUP_2ND_COLUMN + 2 * FWNUM) #define SLIDER_5POS(y, value, label, event, attr) { \ int8_t tmp = value; \ @@ -88,6 +88,9 @@ enum MenuRadioSetupItems { CASE_PWM_BACKLIGHT(ITEM_SETUP_BACKLIGHT_BRIGHTNESS_ON) ITEM_SETUP_FLASH_BEEP, CASE_SPLASH_PARAM(ITEM_SETUP_DISABLE_SPLASH) +#if defined(PXX2) + ITEM_RADIO_OWNER_ID, +#endif CASE_GPS(ITEM_SETUP_TIMEZONE) ITEM_SETUP_ADJUST_RTC, CASE_GPS(ITEM_SETUP_GPSFORMAT) @@ -97,6 +100,7 @@ enum MenuRadioSetupItems { IF_FAI_CHOICE(ITEM_SETUP_FAI) ITEM_SETUP_SWITCHES_DELAY, CASE_STM32(ITEM_SETUP_USB_MODE) + CASE_JACK_DETECT(ITEM_SETUP_JACK_MODE) ITEM_SETUP_RX_CHANNEL_ORD, ITEM_SETUP_STICK_MODE_LABELS, ITEM_SETUP_STICK_MODE, @@ -131,7 +135,38 @@ void menuRadioSetup(event_t event) } #endif - MENU(STR_MENURADIOSETUP, menuTabGeneral, MENU_RADIO_SETUP, HEADER_LINE+ITEM_SETUP_MAX, { HEADER_LINE_COLUMNS CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) 0, 0, 0, 0, 0, CASE_AUDIO(0) CASE_VARIO(LABEL(VARIO)) CASE_VARIO(0) CASE_VARIO(0) CASE_VARIO(0) CASE_VARIO(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_CAPACITY(0) CASE_PCBSKY9X(0) 0, 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, 0, CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) 0, CASE_GPS(0) CASE_PXX(0) 0, 0, IF_FAI_CHOICE(0) 0, CASE_STM32(0) 0, COL_TX_MODE, 0, 1/*to force edit mode*/}); + MENU(STR_MENURADIOSETUP, menuTabGeneral, MENU_RADIO_SETUP, HEADER_LINE+ITEM_SETUP_MAX, { + HEADER_LINE_COLUMNS CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) + LABEL(SOUND), CASE_AUDIO(0) + CASE_BUZZER(0) + 0, 0, 0, 0, 0, CASE_AUDIO(0) + CASE_VARIO(LABEL(VARIO)) + CASE_VARIO(0) + CASE_VARIO(0) + CASE_VARIO(0) + CASE_VARIO(0) + CASE_HAPTIC(LABEL(HAPTIC)) + CASE_HAPTIC(0) + CASE_HAPTIC(0) + CASE_HAPTIC(0) + 0, LABEL(ALARMS), 0, CASE_CAPACITY(0) + CASE_PCBSKY9X(0) + 0, 0, 0, 0, IF_ROTARY_ENCODERS(0) + LABEL(BACKLIGHT), 0, 0, 0, CASE_PWM_BACKLIGHT(0) + CASE_PWM_BACKLIGHT(0) + 0, + CASE_SPLASH_PARAM(0) +#if defined(PXX2) + 0 /* owner registration ID */, +#endif + CASE_GPS(0) + 0, CASE_GPS(0) + CASE_PXX(0) + 0, 0, IF_FAI_CHOICE(0) + 0, + CASE_STM32(0) // USB mode + CASE_JACK_DETECT(0) // Jack mode + 0, COL_TX_MODE, 0, 1/*to force edit mode*/}); if (event == EVT_ENTRY) { reusableBuffer.generalSettings.stickMode = g_eeGeneral.stickMode; @@ -156,11 +191,11 @@ void menuRadioSetup(event_t event) switch (j) { case 0: lcdDrawNumber(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+TM_YEAR_BASE, rowattr|RIGHT); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0); + if (rowattr && s_editMode > 0) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0); break; case 1: lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0|RIGHT, 2); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0); + if (rowattr && s_editMode > 0) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0); break; case 2: { @@ -169,7 +204,7 @@ void menuRadioSetup(event_t event) static const uint8_t dmon[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; dlim += dmon[t.tm_mon]; lcdDrawNumber(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0|RIGHT, 2); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0); + if (rowattr && s_editMode > 0) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0); break; } } @@ -187,15 +222,15 @@ void menuRadioSetup(event_t event) switch (j) { case 0: lcdDrawNumber(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0|RIGHT, 2); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0); + if (rowattr && s_editMode > 0) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0); break; case 1: lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0|RIGHT, 2); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0); + if (rowattr && s_editMode > 0) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0); break; case 2: lcdDrawNumber(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0|RIGHT, 2); - if (rowattr && (s_editMode>0 || p1valdiff)) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0); + if (rowattr && s_editMode > 0) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0); break; } } @@ -467,6 +502,12 @@ void menuRadioSetup(event_t event) } #endif +#if defined(PXX2) + case ITEM_RADIO_OWNER_ID: + editSingleName(RADIO_SETUP_2ND_COLUMN, y, STR_OWNER_ID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID, event, attr); + break; +#endif + #if defined(TELEMETRY_FRSKY) && defined(GPS) case ITEM_SETUP_TIMEZONE: lcdDrawTextAlignedLeft(y, STR_TIMEZONE); @@ -512,7 +553,7 @@ void menuRadioSetup(event_t event) if (g_eeGeneral.fai) POPUP_WARNING("FAI\001mode blocked!"); else - POPUP_CONFIRMATION("FAI mode?"); + POPUP_CONFIRMATION("FAI mode?", nullptr); } break; #endif @@ -524,11 +565,19 @@ void menuRadioSetup(event_t event) lcdDrawText(lcdLastRightPos, y, STR_MS, attr); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.switchesDelay, -15, 100-15); break; + #if defined(STM32) case ITEM_SETUP_USB_MODE: g_eeGeneral.USBMode = editChoice(RADIO_SETUP_2ND_COLUMN, y, STR_USBMODE, STR_USBMODES, g_eeGeneral.USBMode, USB_UNSELECTED_MODE, USB_MAX_MODE, attr, event); break; #endif + +#if defined(JACK_DETECT_GPIO) + case ITEM_SETUP_JACK_MODE: + g_eeGeneral.jackMode = editChoice(RADIO_SETUP_2ND_COLUMN, y, STR_JACKMODE, STR_JACKMODES, g_eeGeneral.jackMode, JACK_UNSELECTED_MODE, JACK_MAX_MODE, attr, event); + break; +#endif + case ITEM_SETUP_RX_CHANNEL_ORD: lcdDrawTextAlignedLeft(y, STR_RXCHANNELORD); // RAET->AETR for (uint8_t i=1; i<=4; i++) { diff --git a/radio/src/gui/128x64/radio_version.cpp b/radio/src/gui/128x64/radio_version.cpp index 66c27cbef..9383f753b 100644 --- a/radio/src/gui/128x64/radio_version.cpp +++ b/radio/src/gui/128x64/radio_version.cpp @@ -18,8 +18,217 @@ * GNU General Public License for more details. */ +#include #include "opentx.h" +// TODO duplicated code +#if defined(PCBX7) || defined(PCBX9E) || defined(PCBX3) +#define EVT_KEY_NEXT_LINE EVT_ROTARY_RIGHT +#define EVT_KEY_PREVIOUS_LINE EVT_ROTARY_LEFT +#else +#define EVT_KEY_NEXT_LINE EVT_KEY_FIRST(KEY_DOWN) +#define EVT_KEY_PREVIOUS_LINE EVT_KEY_FIRST(KEY_UP) +#endif + +#define MENU_BODY_TOP (FH + 1) +#define MENU_BODY_BOTTOM (LCD_H) + +#if defined(PXX2) +void drawPXX2Version(coord_t x, coord_t y, PXX2Version version) +{ + lcdDrawNumber(x, y, version.major, LEFT); + lcdDrawChar(lcdNextPos, y, '.'); + lcdDrawNumber(lcdNextPos, y, version.minor, LEFT); + lcdDrawChar(lcdNextPos, y, '.'); + lcdDrawNumber(lcdNextPos, y, version.revision, LEFT); +} + +void drawPXX2FullVersion(coord_t x, coord_t y, PXX2Version hwVersion, PXX2Version swVersion) +{ + drawPXX2Version(x, y, hwVersion); + lcdDrawText(lcdNextPos, y, "/"); + drawPXX2Version(lcdNextPos, y, swVersion); +} + +static const char * const modulesModels[] = { + "---", + "XJT", + "IXJT", + "IXJT-PRO", + "IXJT-S", + "R9M", + "R9MLite", + "R9MLite-PRO", +}; + +static const char * const receiversModels[] = { + "---", + "X8R", + "RX8R", + "RX8R-PRO", + "RX6R", + "RX4R", + "G-RX8", + "G-RX6", + "X6R", + "X4R", + "X4R-SB", + "XSR", + "XSR-M", + "RXSR", + "S6R", + "S8R", + "XM", + "XM+", + "XMR", + "R9", + "R9-SLIM", + "R9-SLIM+", + "R9-MINI", + "R9-MM", + "R9-STAB", +}; + +void menuRadioModulesVersion(event_t event) +{ + if (menuEvent) { + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + moduleSettings[EXTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + return; + } + + TITLE("MODULES / RX VERSION"); + + if (event == EVT_ENTRY || get_tmr10ms() >= reusableBuffer.hardwareAndSettings.updateTime) { + // menuVerticalOffset = 0; + + memclear(&reusableBuffer.hardwareAndSettings.modules, sizeof(reusableBuffer.hardwareAndSettings.modules)); + + if (isModulePXX2(INTERNAL_MODULE) && IS_INTERNAL_MODULE_ON()) { + reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].current = PXX2_HW_INFO_TX_ID; + reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].maximum = MAX_RECEIVERS_PER_MODULE - 1; + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_GET_HARDWARE_INFO; + } + + if (isModulePXX2(EXTERNAL_MODULE) && IS_EXTERNAL_MODULE_ON()) { + reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].current = PXX2_HW_INFO_TX_ID; + reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].maximum = MAX_RECEIVERS_PER_MODULE - 1; + moduleSettings[EXTERNAL_MODULE].mode = MODULE_MODE_GET_HARDWARE_INFO; + } + + reusableBuffer.hardwareAndSettings.updateTime = get_tmr10ms() + 1000 /* 10s*/; + } + + coord_t y = (FH + 1) - menuVerticalOffset * FH; + + for (uint8_t module=0; module= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + if (module == INTERNAL_MODULE) + lcdDrawTextAlignedLeft(y, "Internal module"); + else if (module == EXTERNAL_MODULE) + lcdDrawTextAlignedLeft(y, "External module"); + } + y += FH; + + // Module model + if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + lcdDrawText(INDENT_WIDTH, y, "Model"); + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].information.modelID; + if (modelId >= DIM(modulesModels)) + modelId = 0; + lcdDrawText(12 * FW, y, modulesModels[modelId]); + } + y += FH; + + // Module version + if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + lcdDrawText(INDENT_WIDTH, y, "Version"); + if (reusableBuffer.hardwareAndSettings.modules[module].information.modelID) { + drawPXX2FullVersion(12 * FW, y, reusableBuffer.hardwareAndSettings.modules[module].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].information.swVersion); + } + } + y += FH; + + for (uint8_t receiver=0; receiver= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + lcdDrawText(INDENT_WIDTH, y, "Receiver"); + lcdDrawNumber(lcdLastRightPos + 2, y, receiver + 1); + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.modelID; + if (modelId >= DIM(receiversModels)) + modelId = 0; + lcdDrawText(12 * FW, y, receiversModels[modelId]); + } + y += FH; + + // Receiver version + if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) { + drawPXX2FullVersion(12 * FW, y, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.swVersion); + } + y += FH; + } + } + } + + uint8_t lines = (y - (FH + 1)) / FH + menuVerticalOffset; + if (lines > NUM_BODY_LINES) { + drawVerticalScrollbar(LCD_W-1, FH, LCD_H-FH, menuVerticalOffset, lines, NUM_BODY_LINES); + } + else { + menuVerticalOffset = 0; + } + + switch(event) { + case EVT_KEY_PREVIOUS_LINE: + if (lines > NUM_BODY_LINES) { + if (menuVerticalOffset-- == 0) + menuVerticalOffset = lines - 1; + } + break; + + case EVT_KEY_NEXT_LINE: + if (lines > NUM_BODY_LINES) { + if (++menuVerticalOffset + NUM_BODY_LINES > lines) + menuVerticalOffset = 0; + } + break; + + case EVT_KEY_BREAK(KEY_EXIT): + if (menuVerticalOffset != 0) + menuVerticalOffset = 0; + else + popMenu(); + break; + } +} +#endif + +enum MenuRadioVersionItems +{ + ITEM_RADIO_VERSION_FIRST = HEADER_LINE - 1, +#if defined(PXX2) + ITEM_RADIO_MODULES_VERSION, +#endif +#if defined(EEPROM_RLC) + ITEM_RADIO_BACKUP_EEPROM, + ITEM_RADIO_FACTORY_RESET, +#endif + ITEM_RADIO_VERSION_COUNT +}; + void menuRadioVersion(event_t event) { #if defined(EEPROM_RLC) @@ -31,40 +240,46 @@ void menuRadioVersion(event_t event) } #endif - SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, MENU_RADIO_VERSION, 1); + SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, MENU_RADIO_VERSION, ITEM_RADIO_VERSION_COUNT); - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+FH, vers_stamp); + coord_t y = MENU_HEADER_HEIGHT + 1; + lcdDrawTextAlignedLeft(y, vers_stamp); + y += 4*FH; + // TODO this was good on AVR radios, but horrible now ... #if defined(COPROCESSOR) if (Coproc_valid == 1) { - lcdDrawTextAlignedLeft(6*FH, "CoPr:"); - lcdDraw8bitsNumber(10*FW, 6*FH, Coproc_read); + lcdDrawTextAlignedLeft(y, "CoPr:"); + lcdDraw8bitsNumber(10*FW, y, Coproc_read); } else { - lcdDrawTextAlignedLeft(6*FH, "CoPr: ---"); + lcdDrawTextAlignedLeft(y, "CoPr: ---"); } -#elif defined(EEPROM_RLC) - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+5*FH+1, STR_EEBACKUP); - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+6*FH+1, STR_FACTORYRESET); - lcdDrawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID); + y += FH; +#endif -#if defined(PCBXLITE) - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(KEY_ENTER); - if (IS_SHIFT_PRESSED()) { - POPUP_CONFIRMATION(STR_CONFIRMRESET); - } - else { - eepromBackup(); - } +#if defined(PXX2) + lcdDrawText(INDENT_WIDTH, y, BUTTON("Modules / RX version"), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0); + y += FH; + if (menuVerticalPosition == ITEM_RADIO_MODULES_VERSION && event == EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = EDIT_SELECT_FIELD; + pushMenu(menuRadioModulesVersion); } -#else - if (event == EVT_KEY_LONG(KEY_ENTER)) { +#endif + +#if defined(EEPROM_RLC) + lcdDrawText(INDENT_WIDTH, y, BUTTON(STR_EEBACKUP), menuVerticalPosition == ITEM_RADIO_BACKUP_EEPROM ? INVERS : 0); + y += FH; + if (menuVerticalPosition == ITEM_RADIO_BACKUP_EEPROM && event == EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = EDIT_SELECT_FIELD; eepromBackup(); } - else if (event == EVT_KEY_LONG(KEY_MENU)) { - POPUP_CONFIRMATION(STR_CONFIRMRESET); + + lcdDrawText(INDENT_WIDTH, y, BUTTON(STR_FACTORYRESET), menuVerticalPosition == ITEM_RADIO_FACTORY_RESET ? INVERS : 0); + // y += FH; + if (menuVerticalPosition == ITEM_RADIO_FACTORY_RESET && event == EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = EDIT_SELECT_FIELD; + POPUP_CONFIRMATION(STR_CONFIRMRESET, nullptr); } #endif -#endif } diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 43401c55e..6be26d9e9 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -143,7 +143,7 @@ void displayTrims(uint8_t phase) } if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<0 ? 12 : 40, xm-2, -abs(dir/5), TINSIZE|VERTICAL); + lcdDrawNumber(dir>0 ? 12 : 40, xm-2, -abs(dir), TINSIZE|VERTICAL); } } } @@ -165,7 +165,7 @@ void displayTrims(uint8_t phase) } if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<0 ? TRIM_LH_POS : TRIM_LH_NEG) : (dir>0 ? TRIM_RH_POS : TRIM_RH_NEG)), ym-2, -abs(dir/5), TINSIZE); + lcdDrawNumber((stickIndex==0 ? (dir>0 ? TRIM_LH_POS : TRIM_LH_NEG) : (dir>0 ? TRIM_RH_POS : TRIM_RH_NEG)), ym-2, -abs(dir), TINSIZE); } } } @@ -227,7 +227,7 @@ void displayVoltageOrAlarm() #define displayVoltageOrAlarm() displayBattVoltage() #endif -#if defined(PCBX7) +#if defined(PCBX7) || defined(PCBX3) #define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER) #define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGE) #define EVT_KEY_NEXT_PAGE EVT_ROTARY_RIGHT @@ -258,7 +258,6 @@ void displayVoltageOrAlarm() #define EVT_KEY_STATISTICS EVT_KEY_LONG(KEY_UP) #endif -#if defined(NAVIGATION_MENUS) void onMainViewMenu(const char *result) { if (result == STR_RESET_TIMER1) { @@ -299,7 +298,6 @@ void onMainViewMenu(const char *result) chainMenu(menuAboutView); } } -#endif void menuMainView(event_t event) { @@ -334,7 +332,6 @@ void menuMainView(event_t event) } break; -#if defined(NAVIGATION_MENUS) case EVT_KEY_CONTEXT_MENU: killEvents(event); @@ -348,7 +345,6 @@ void menuMainView(event_t event) POPUP_MENU_ADD_ITEM(STR_ABOUT_US); POPUP_MENU_START(onMainViewMenu); break; -#endif #if MENUS_LOCK != 2 /*no menus*/ #if defined(EVT_KEY_LAST_MENU) @@ -403,23 +399,12 @@ void menuMainView(event_t event) break; case EVT_KEY_FIRST(KEY_EXIT): -#if defined(GVARS) && !defined(PCBSTD) +#if defined(GVARS) if (gvarDisplayTimer > 0) { gvarDisplayTimer = 0; } -#endif -#if !defined(NAVIGATION_MENUS) - if (view == VIEW_TIMER2) { - timerReset(1); - } #endif break; - -#if !defined(NAVIGATION_MENUS) - case EVT_KEY_LONG(KEY_EXIT): - flightReset(); - break; -#endif } { @@ -499,7 +484,17 @@ void menuMainView(event_t event) doMainScreenGraphics(); // Switches -#if defined(PCBTARANIS) +#if defined(PCBX3) + static const uint8_t x[NUM_SWITCHES] = {2*FW-2, 2*FW-2, 16*FW+1, 2*FW-2, 16*FW+1}; + static const uint8_t y[NUM_SWITCHES] = {4*FH+1, 5*FH+1, 5*FH+1, 6*FH+1, 6*FH+1}; + for (int i=0; i 0) { gvarDisplayTimer--; warningText = STR_GLOBAL_VAR; - drawMessageBox(); + drawMessageBox(warningText); lcdDrawSizedText(16, 5*FH, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, ZCHAR); lcdDrawText(16+6*FW, 5*FH, "[", BOLD); drawGVarValue(lcdLastRightPos, 5*FH, gvarLastChanged, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), LEFT|BOLD); @@ -573,7 +568,7 @@ void menuMainView(event_t event) #endif #if defined(DSM2) - if (moduleFlag[0] == MODULE_BIND) { + if (moduleSettings[0].mode == MODULE_MODE_BIND) { // Issue 98 lcdDrawText(15*FW, 0, "BIND", 0); } diff --git a/radio/src/gui/128x64/widgets.cpp b/radio/src/gui/128x64/widgets.cpp index cec799981..6ac179599 100644 --- a/radio/src/gui/128x64/widgets.cpp +++ b/radio/src/gui/128x64/widgets.cpp @@ -74,7 +74,7 @@ choice_t editChoice(coord_t x, coord_t y, const char * label, const char *values { drawFieldLabel(x, y, label); if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); - if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); + if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); return value; } @@ -230,22 +230,6 @@ void drawStatusLine() } #endif -void drawProgressBar(const char * label, int num, int den) -{ - lcdClear(); - if (label) { - lcdDrawTextAlignedLeft(4*FH, label); - } - lcdDrawRect(4, 6*FH+4, LCD_W-8, 7); - if (num > 0 && den > 0) { - int width = ((LCD_W-12)*num)/den; - lcdDrawSolidHorizontalLine(6, 6*FH+6, width, FORCE); - lcdDrawSolidHorizontalLine(6, 6*FH+7, width, FORCE); - lcdDrawSolidHorizontalLine(6, 6*FH+8, width, FORCE); - } - lcdRefresh(); -} - const unsigned char SLEEP_BITMAP[] = { #include "sleep.lbm" }; diff --git a/radio/src/gui/212x64/gui.h b/radio/src/gui/212x64/gui.h index 843cc41d9..6922ae328 100644 --- a/radio/src/gui/212x64/gui.h +++ b/radio/src/gui/212x64/gui.h @@ -32,7 +32,6 @@ #define DEFAULT_SCROLLBAR_X (LCD_W-1) #define NUM_BODY_LINES (LCD_LINES-1) #define MENU_HEADER_HEIGHT FH -#define MENU_INIT_VPOS 0 #define MODEL_BITMAP_WIDTH 64 #define MODEL_BITMAP_HEIGHT 32 @@ -55,11 +54,6 @@ inline void drawFieldLabel(coord_t x, coord_t y, const char * str) extern uint8_t modelBitmap[MODEL_BITMAP_SIZE]; bool loadModelBitmap(char * name, uint8_t * bitmap); -struct MenuItem { - const char * name; - const MenuHandlerFunc action; -}; - // Temporary no highlight extern uint8_t noHighlightCounter; #define NO_HIGHLIGHT() (noHighlightCounter > 0) @@ -71,8 +65,6 @@ void drawSplash(); void drawSecondSplash(); void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr); void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); -void displayMenuBar(const MenuItem * menu, int index); -void drawProgressBar(const char * label, int num, int den); void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); void drawColumnHeader(const char * const * headers, uint8_t index); void drawStick(coord_t centrex, int16_t xval, int16_t yval); @@ -86,15 +78,13 @@ typedef uint16_t FlightModesType; extern int8_t checkIncDec_Ret; // global helper vars -#define EDIT_SELECT_MENU -1 #define EDIT_SELECT_FIELD 0 #define EDIT_MODIFY_FIELD 1 #define EDIT_MODIFY_STRING 2 extern int8_t s_editMode; // global editmode // checkIncDec flags -#define EE_GENERAL 0x01 -#define EE_MODEL 0x02 +// we leave room for EE_MODEL and EE_GENERAL #define NO_INCDEC_MARKS 0x04 #define INCDEC_SWITCH 0x08 #define INCDEC_SOURCE 0x10 @@ -107,7 +97,8 @@ extern int8_t s_editMode; // global editmode #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) // mawrow special values -#define TITLE_ROW ((uint8_t)-1) +#define READONLY_ROW ((uint8_t)-1) +#define TITLE_ROW READONLY_ROW #define HIDDEN_ROW ((uint8_t)-2) struct CheckIncDecStops @@ -257,15 +248,10 @@ uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint #define WARNING_TYPE_ASTERISK 0 #define WARNING_TYPE_CONFIRM 1 #define WARNING_TYPE_INPUT 2 +#define WARNING_TYPE_INFO 4 void copySelection(char * dst, const char * src, uint8_t size); -extern const char * warningText; -extern const char * warningInfoText; -extern uint8_t warningInfoLength; -extern uint8_t warningResult; -extern uint8_t warningType; - #define COPY_MODE 1 #define MOVE_MODE 2 extern uint8_t s_copyMode; diff --git a/radio/src/gui/212x64/lcd.cpp b/radio/src/gui/212x64/lcd.cpp index 104bbcc34..0ba2ef825 100644 --- a/radio/src/gui/212x64/lcd.cpp +++ b/radio/src/gui/212x64/lcd.cpp @@ -244,7 +244,7 @@ uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags) { uint8_t width = 0; for (int i=0; len==0 || i + +extern uint8_t g_moduleIdx; + +void menuModelFailsafe(event_t event) +{ + static uint8_t maxNameLen = 4; + static int8_t lastModel = g_eeGeneral.currModel; + const coord_t barH = (LCD_H - FH) / 8 - 1; + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; + uint8_t cols = 1; + uint8_t colW = LCD_W; + + if (lastModel != g_eeGeneral.currModel) { + lastModel = g_eeGeneral.currModel; + maxNameLen = 4; + } + + if (event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + event = 0; + + if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { + if (s_editMode) { + g_model.failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; + s_editMode = 0; + } + else { + int16_t & failsafe = g_model.failsafeChannels[menuVerticalPosition]; + if (failsafe < FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_HOLD; + else if (failsafe == FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_NOPULSE; + else + failsafe = 0; + } + } + else { + // "Outputs => Failsafe" menu item + setCustomFailsafe(g_moduleIdx); + } + + storageDirty(EE_MODEL); + AUDIO_WARNING1(); + SEND_FAILSAFE_NOW(g_moduleIdx); + } + + SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1); + SET_SCROLLBAR_X(0); + + if (sentModuleChannels(g_moduleIdx) > 8) { + cols = 2; + colW = LCD_W / cols - 1; + // Column separator + if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { + lcdDrawSolidVerticalLine(colW, FH, LCD_H - (FH*2 + FH/2 + 2)); + } + else { + lcdDrawSolidVerticalLine(colW, FH, LCD_H - FH); + } + } + + lcdDrawTextAlignedCenter(0, FAILSAFESET); + lcdInvertLine(0); + + coord_t x = colW; + for (uint8_t col = 0; col < cols; col++) { + + coord_t y = FH + 1; + uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); + uint8_t ch = line + col*8; + + for (; line < 8; line++) { + const int32_t channelValue = channelOutputs[ch+channelStart]; + int32_t failsafeValue = g_model.failsafeChannels[8*col+line]; + uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name); + uint8_t barW = colW - FW * maxNameLen - FWNUM * 3; // default bar width + +#if defined(PPM_UNIT_PERCENT_PREC1) + barW -= FWNUM + 1; +#endif + barW += (barW % 2); + + // Channel name if present, number if not + if (lenLabel > 0) { + if (lenLabel > maxNameLen) + maxNameLen = lenLabel; + lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE); + } + else { + putsChn(x - colW, y, ch+1, SMLSIZE); + } + + // Value + LcdFlags flags = TINSIZE; + if (menuVerticalPosition == ch) { + flags |= INVERS; + if (s_editMode) { + if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + s_editMode = 0; + } + else { + flags |= BLINK; + CHECK_INCDEC_MODELVAR(event, g_model.failsafeChannels[8*col+line], -lim, +lim); + } + } + } + + const coord_t xValue = x - barW; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); + failsafeValue = 0; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); + failsafeValue = 0; + } + else { +#if defined(PPM_UNIT_US) + lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); +#elif defined(PPM_UNIT_PERCENT_PREC1) + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); +#else + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); +#endif + } + + // Gauge + lcdDrawRect(x - barW, y, barW - 1, barH); + barW = barW / 2 - 1; + const coord_t lenChannel = limit(1, (abs(channelValue) * barW + lim / 2) / lim, barW); + const coord_t lenFailsafe = limit(1, (abs(failsafeValue) * barW + lim / 2) / lim, barW); + const coord_t barX = x - barW - 2; + const coord_t xChannel = (channelValue >= 0) ? barX : barX - lenChannel + 1; + const coord_t xFailsafe = (failsafeValue > 0) ? barX : barX - lenFailsafe + 1; + lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); + lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); + lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); + lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); + + if (++ch >= sentModuleChannels(g_moduleIdx)) + break; + + y += barH + 1; + + } // channels + + x += colW + 2; + + } // columns + + if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { + // Outputs => Failsafe + lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); + } +} diff --git a/radio/src/io/pxx2.h b/radio/src/gui/212x64/model_module_options.cpp similarity index 84% rename from radio/src/io/pxx2.h rename to radio/src/gui/212x64/model_module_options.cpp index 3a1506a67..f72d3594f 100644 --- a/radio/src/io/pxx2.h +++ b/radio/src/gui/212x64/model_module_options.cpp @@ -18,10 +18,4 @@ * GNU General Public License for more details. */ -#ifndef _IO_PXX2_H_ -#define _IO_PXX2_H_ - -#define PXX2_BAUDRATE 230400 -#define PXX2_PERIOD 4 // 4ms - -#endif +#include diff --git a/radio/src/gui/212x64/model_receiver_options.cpp b/radio/src/gui/212x64/model_receiver_options.cpp new file mode 100644 index 000000000..f72d3594f --- /dev/null +++ b/radio/src/gui/212x64/model_receiver_options.cpp @@ -0,0 +1,21 @@ +/* + * 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. + */ + +#include diff --git a/radio/src/gui/212x64/model_select.cpp b/radio/src/gui/212x64/model_select.cpp index 7eb4bb8a3..758abc31b 100644 --- a/radio/src/gui/212x64/model_select.cpp +++ b/radio/src/gui/212x64/model_select.cpp @@ -52,10 +52,10 @@ void onModelSelectMenu(const char * result) else if (result == STR_DELETE_MODEL) { char * nametmp = reusableBuffer.modelsel.mainname; strcat_modelname (nametmp, sub); - POPUP_CONFIRMATION(STR_DELETEMODEL); + POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(nametmp, sizeof(g_model.header.name), 0); } - else { + else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); POPUP_WARNING(eeRestoreModel(sub, (char *)result)); @@ -102,7 +102,7 @@ void menuModelSelect(event_t event) if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { char * nametmp = reusableBuffer.modelsel.mainname; strcat_modelname (nametmp, sub); - POPUP_CONFIRMATION(STR_DELETEMODEL); + POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(nametmp, sizeof(g_model.header.name), 0); killEvents(event); break; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 4f8c5ead2..02626db28 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -88,6 +88,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, + ITEM_MODEL_EXTERNAL_MODULE_FREQ, ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, ITEM_MODEL_TRAINER_LINE1, @@ -103,7 +104,7 @@ enum MenuModelSetupItems { #define MODEL_SETUP_RANGE_OFS 7*FW #define MODEL_SETUP_SET_FAILSAFE_OFS 10*FW-2 -#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) +#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) void onBindMenu(const char * result) { @@ -129,7 +130,7 @@ void onBindMenu(const char * result) return; } - moduleFlag[moduleIdx] = MODULE_BIND; + moduleSettings[moduleIdx].mode = MODULE_MODE_BIND; } void copySelection(char * dst, const char * src, uint8_t size) @@ -147,7 +148,7 @@ void onModelSetupBitmapMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a bmp file in the list copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); @@ -239,21 +240,22 @@ int getSwitchWarningsCount() #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) #endif #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) -#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1) + #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) #if defined(BLUETOOTH) && defined(USEHORUSBT) #define TRAINER_LINE1_BLUETOOTH_M_ROWS ((bluetoothDistantAddr[0] == 0 || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) - #define TRAINER_LINE1_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)1 : (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_LINE1_BLUETOOTH_M_ROWS : (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH ? (uint8_t)1 : HIDDEN_ROW))) - #define TRAINER_LINE2_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_LINE1_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)1 : (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_LINE1_BLUETOOTH_M_ROWS : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? (uint8_t)1 : HIDDEN_ROW))) + #define TRAINER_LINE2_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) #else - #define TRAINER_LINE1_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)1 : HIDDEN_ROW) - #define TRAINER_LINE2_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) + #define TRAINER_LINE1_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)1 : HIDDEN_ROW) + #define TRAINER_LINE2_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) #endif #define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0 -#define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : isModuleMultimodule(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0 +#define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +#define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, #if TIMERS == 1 #define TIMERS_ROWS TIMER_ROWS(0) @@ -296,18 +298,19 @@ void menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, + EXTRA_MODULE_ROWS LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS}); MENU_CHECK(STR_MENUSETUP, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_MAX); if (event == EVT_ENTRY) { - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; } #if (defined(DSM2) || defined(PXX)) if (menuEvent) { - moduleFlag[0] = 0; - moduleFlag[1] = 0; + moduleSettings[0].mode = 0; + moduleSettings[1].mode = 0; } #endif @@ -710,9 +713,9 @@ void menuModelSetup(event_t event) #endif case ITEM_MODEL_TRAINER_MODE: lcdDrawTextAlignedLeft(y, STR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, attr); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr); if (attr) { - g_model.trainerMode = checkIncDec(event, g_model.trainerMode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable); + g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable); } #if defined(BLUETOOTH) && defined(USEHORUSBT) if (attr && checkIncDec_Ret) { @@ -733,8 +736,8 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); - else if (isModuleR9M(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + else if (isR9ModuleRunning(EXTERNAL_MODULE)) + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -757,7 +760,7 @@ void menuModelSetup(event_t event) if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: - g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable); + g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : MODULE_TYPE_COUNT-1, EE_MODEL, isExternalModuleAvailable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; @@ -771,15 +774,6 @@ void menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); - else if (isModuleR9M(EXTERNAL_MODULE)) { - uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); - if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { - POPUP_WARNING(STR_R9MFLEXWARN1); - const char * w = STR_R9MFLEXWARN2; - SET_WARNING_INFO(w, strlen(w), 0); - } - g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; - } #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -835,7 +829,7 @@ void menuModelSetup(event_t event) #if defined(BLUETOOTH) && defined(USEHORUSBT) case ITEM_MODEL_TRAINER_LINE1: - if (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH) { + if (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH) { if (attr) { s_editMode = 0; } @@ -876,7 +870,24 @@ void menuModelSetup(event_t event) // no break #else case ITEM_MODEL_TRAINER_LINE1: + lcdDrawTextAlignedLeft(y, STR_CHANNELRANGE); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); + lcdDrawNumber(lcdLastRightPos, y, g_model.trainerData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); + lcdDrawChar(lcdLastRightPos, y, '-'); + lcdDrawNumber(lcdLastRightPos + FW+1, y, g_model.trainerData.channelsStart+8+g_model.trainerData.channelsCount, LEFT | (menuHorizontalPosition==1 ? attr : 0)); + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.trainerData.channelsStart, 32-8-g_model.trainerData.channelsCount); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.channelsCount, -4, min(MAX_TRAINER_CHANNELS_M8, 32-8-g_model.trainerData.channelsStart)); + break; + } + } + break; #endif + case ITEM_MODEL_INTERNAL_MODULE_CHANNELS: case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS: { @@ -917,9 +928,30 @@ void menuModelSetup(event_t event) break; } + case ITEM_MODEL_TRAINER_LINE2: + lcdDrawTextAlignedLeft(y, STR_PPMFRAME); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.trainerData.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); + lcdDrawText(lcdLastRightPos, y, STR_MS); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+6*FW, y, (g_model.trainerData.delay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); + lcdDrawChar(lcdLastRightPos, y, 'u'); + lcdDrawChar(MODEL_SETUP_2ND_COLUMN+12*FW, y, g_model.trainerData.pulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0); + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.frameLength, -20, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.delay, -4, 10); + break; + case 2: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.trainerData.pulsePol, 1); + break; + } + } + break; + case ITEM_MODEL_INTERNAL_MODULE_BIND: case ITEM_MODEL_EXTERNAL_MODULE_BIND: - case ITEM_MODEL_TRAINER_LINE2: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; @@ -1029,27 +1061,27 @@ void menuModelSetup(event_t event) POPUP_MENU_START(onBindMenu); continue; } - if (moduleFlag[moduleIdx] == MODULE_BIND) { - newFlag = MODULE_BIND; + if (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND) { + newFlag = MODULE_MODE_BIND; } else { - if (!popupMenuNoItems) { + if (!popupMenuItemsCount) { s_editMode = 0; // this is when popup is exited before a choice is made } } } else { - newFlag = MODULE_BIND; + newFlag = MODULE_MODE_BIND; } } else if (l_posHorz == 2) { - newFlag = MODULE_RANGECHECK; + newFlag = MODULE_MODE_RANGECHECK; } } } - moduleFlag[moduleIdx] = newFlag; + moduleSettings[moduleIdx].mode = newFlag; #if defined(MULTIMODULE) - if (newFlag == MODULE_BIND) + if (newFlag == MODULE_MODE_BIND) multiBindStatus = MULTI_BIND_INITIATED; #endif } @@ -1129,16 +1161,7 @@ void menuModelSetup(event_t event) } } #endif - if (isModuleR9M(moduleIdx)) { - lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY); - if (IS_TELEMETRY_INTERNAL_MODULE()) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); - } - else { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); - } - } - else if (isModuleSBUS(moduleIdx)) { + if (isModuleSBUS(moduleIdx)) { lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); } @@ -1159,10 +1182,10 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_LBT_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr); if (attr) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, R9M_LBT_POWER_MAX); - if (attr && s_editMode == 0 && reusableBuffer.modelsetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { - if((reusableBuffer.modelsetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) //switching between mode 2 and 3 does not require rebind + if (attr && s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { + if((reusableBuffer.moduleSetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) //switching between mode 2 and 3 does not require rebind POPUP_WARNING(STR_REBIND); - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; } } } @@ -1174,6 +1197,18 @@ void menuModelSetup(event_t event) break; } + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); + } + } + break; + #if defined (MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) @@ -1205,7 +1240,7 @@ void menuModelSetup(event_t event) #if defined(PXX) if (IS_RANGECHECK_ENABLE()) { showMessageBox("RSSI: "); - lcdDrawNumber(16+4*FW, 5*FH, TELEMETRY_RSSI(), BOLD); + lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD | LEFT); } #endif @@ -1223,157 +1258,3 @@ void menuModelSetup(event_t event) } } } - -void menuModelFailsafe(event_t event) -{ - static uint8_t maxNameLen = 4; - static int8_t lastModel = g_eeGeneral.currModel; - const coord_t barH = (LCD_H - FH) / 8 - 1; - const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; - const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; - uint8_t cols = 1; - uint8_t colW = LCD_W; - - if (lastModel != g_eeGeneral.currModel) { - lastModel = g_eeGeneral.currModel; - maxNameLen = 4; - } - - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - event = 0; - - if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { - if (s_editMode) { - g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; - s_editMode = 0; - } - else { - int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition]; - if (failsafe < FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_HOLD; - else if (failsafe == FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_NOPULSE; - else - failsafe = 0; - } - } - else { - // "Outputs => Failsafe" menu item - setCustomFailsafe(g_moduleIdx); - } - - storageDirty(EE_MODEL); - AUDIO_WARNING1(); - SEND_FAILSAFE_NOW(g_moduleIdx); - } - - SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx)+1); - SET_SCROLLBAR_X(0); - - if (sentModuleChannels(g_moduleIdx) > 8) { - cols = 2; - colW = LCD_W / cols - 1; - // Column separator - if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { - lcdDrawSolidVerticalLine(colW, FH, LCD_H - (FH*2 + FH/2 + 2)); - } - else { - lcdDrawSolidVerticalLine(colW, FH, LCD_H - FH); - } - } - - lcdDrawTextAlignedCenter(0, FAILSAFESET); - lcdInvertLine(0); - - coord_t x = colW; - for (uint8_t col = 0; col < cols; col++) { - - coord_t y = FH + 1; - uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); - uint8_t ch = line + col*8; - - for (; line < 8; line++) { - const int32_t channelValue = channelOutputs[ch+channelStart]; - int32_t failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; - uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name); - uint8_t barW = colW - FW * maxNameLen - FWNUM * 3; // default bar width - -#if defined(PPM_UNIT_PERCENT_PREC1) - barW -= FWNUM + 1; -#endif - barW += (barW % 2); - - // Channel name if present, number if not - if (lenLabel > 0) { - if (lenLabel > maxNameLen) - maxNameLen = lenLabel; - lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE); - } - else { - putsChn(x - colW, y, ch+1, SMLSIZE); - } - - // Value - LcdFlags flags = TINSIZE; - if (menuVerticalPosition == ch) { - flags |= INVERS; - if (s_editMode) { - if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - s_editMode = 0; - } - else { - flags |= BLINK; - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line], -lim, +lim); - } - } - } - - const coord_t xValue = x - barW; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); - failsafeValue = 0; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); - failsafeValue = 0; - } - else { -#if defined(PPM_UNIT_US) - lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); -#elif defined(PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); -#else - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); -#endif - } - - // Gauge - lcdDrawRect(x - barW, y, barW - 1, barH); - barW = barW / 2 - 1; - const coord_t lenChannel = limit(1, (abs(channelValue) * barW + lim / 2) / lim, barW); - const coord_t lenFailsafe = limit(1, (abs(failsafeValue) * barW + lim / 2) / lim, barW); - const coord_t barX = x - barW - 2; - const coord_t xChannel = (channelValue >= 0) ? barX : barX - lenChannel + 1; - const coord_t xFailsafe = (failsafeValue > 0) ? barX : barX - lenFailsafe + 1; - lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); - lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); - lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); - lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); - - if (++ch >= sentModuleChannels(g_moduleIdx)) - break; - - y += barH + 1; - - } // channels - - x += colW + 2; - - } // columns - - if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { - // Outputs => Failsafe - lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); - } -} diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index 0d911a3bc..3bdbfbc74 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -56,7 +56,7 @@ void onCustomFunctionsFileSelectionMenu(const char * result) POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cfn->play.name, result, sizeof(cfn->play.name)); storageDirty(eeFlags); @@ -129,7 +129,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } diff --git a/radio/src/gui/212x64/model_telemetry.cpp b/radio/src/gui/212x64/model_telemetry.cpp index 13c2f1c21..5c4f5af2d 100644 --- a/radio/src/gui/212x64/model_telemetry.cpp +++ b/radio/src/gui/212x64/model_telemetry.cpp @@ -506,7 +506,7 @@ void menuModelTelemetryFrsky(event_t event) s_editMode = 0; if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { killEvents(KEY_ENTER); - POPUP_CONFIRMATION(STR_CONFIRMDELETE); + POPUP_CONFIRMATION(STR_CONFIRMDELETE, nullptr); } break; diff --git a/radio/src/gui/212x64/popups.cpp b/radio/src/gui/212x64/popups.cpp index dee7c4e72..0802949a5 100644 --- a/radio/src/gui/212x64/popups.cpp +++ b/radio/src/gui/212x64/popups.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -20,30 +20,6 @@ #include "opentx.h" -const char * warningText = NULL; -const char * warningInfoText; -uint8_t warningInfoLength; -uint8_t warningType; -uint8_t warningResult = 0; -uint8_t warningInfoFlags = ZCHAR; -int16_t warningInputValue; -int16_t warningInputValueMin; -int16_t warningInputValueMax; - -void drawMessageBox(const char * title) -{ - lcdDrawFilledRect(10, 16, LCD_W-20, 40, SOLID, ERASE); - lcdDrawRect(10, 16, LCD_W-20, 40); - lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y, title, WARNING_LINE_LEN); - // could be a place for a warningInfoText -} - -void showMessageBox(const char * title) -{ - drawMessageBox(title); - lcdRefresh(); -} - const unsigned char ASTERISK_BITMAP[] = { #include "asterisk.lbm" }; @@ -75,42 +51,3 @@ void drawAlertBox(const char * title, const char * text, const char * action) #undef MESSAGE_LCD_OFFSET } - -void showAlertBox(const char * title, const char * text, const char * action, uint8_t sound) -{ - drawAlertBox(title, text, action); - AUDIO_ERROR_MESSAGE(sound); - lcdRefresh(); - lcdSetContrast(); - clearKeyEvents(); - backlightOn(); - checkBacklight(); -} - -void runPopupWarning(event_t event) -{ - warningResult = false; - drawMessageBox(warningText); - if (warningInfoText) { - lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+FH, warningInfoText, warningInfoLength, WARNING_INFO_FLAGS); - } - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+2*FH, warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS); - switch (event) { - case EVT_KEY_BREAK(KEY_ENTER): - if (warningType == WARNING_TYPE_ASTERISK) - break; - warningResult = true; - // no break - case EVT_KEY_BREAK(KEY_EXIT): - warningText = NULL; - warningType = WARNING_TYPE_ASTERISK; - break; - default: - if (warningType == WARNING_TYPE_INPUT) { - s_editMode = EDIT_MODIFY_FIELD; - warningInputValue = checkIncDec(event, warningInputValue, warningInputValueMin, warningInputValueMax); - s_editMode = EDIT_SELECT_FIELD; - } - break; - } -} diff --git a/radio/src/gui/212x64/popups.h b/radio/src/gui/212x64/popups.h index 06d1be6d7..295419096 100644 --- a/radio/src/gui/212x64/popups.h +++ b/radio/src/gui/212x64/popups.h @@ -21,50 +21,40 @@ #ifndef _POPUPS_H_ #define _POPUPS_H_ +#define MESSAGEBOX_X 10 +#define MESSAGEBOX_Y 16 +#define MESSAGEBOX_W LCD_W - (2 * MESSAGEBOX_X) + #define MENU_X 30 #define MENU_Y 16 -#define MENU_W LCD_W-(2*MENU_X) +#define MENU_W LCD_W - (2 * MENU_X) + #define WARNING_LINE_LEN 32 #define WARNING_LINE_X 16 #define WARNING_LINE_Y 3*FH -void drawMessageBox(const char * title); -void showMessageBox(const char * title); -void runPopupWarning(event_t event); -#define DRAW_MESSAGE_BOX(title) drawMessageBox(title) - -extern void (*popupFunc)(event_t event); -extern int16_t warningInputValue; -extern int16_t warningInputValueMin; -extern int16_t warningInputValueMax; -extern uint8_t warningInfoFlags; - #define DISPLAY_WARNING (*popupFunc) +#define POPUP_INFORMATION(s) (warningText = s, warningType = WARNING_TYPE_INFO, warningInfoText = 0, popupFunc = runPopupWarning) #define POPUP_WARNING(s) (warningText = s, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max) +#define POPUP_CONFIRMATION(s, func) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning, popupMenuHandler = func) +#define POPUP_INPUT(s, func) (warningText = s, popupFunc = func) #define WARNING_INFO_FLAGS warningInfoFlags #define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags) -#define NAVIGATION_MENUS -#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0) -#define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuNoItems ? s : popupMenuNoItems) : 0) +#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuItemsCount++] = s; } while (0) +#define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuItemsCount ? s : popupMenuItemsCount) : 0) #define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while (0) #define POPUP_MENU_MAX_LINES 12 #define MENU_MAX_DISPLAY_LINES 6 #define POPUP_MENU_ADD_SD_ITEM(s) POPUP_MENU_ADD_ITEM(s) #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) #define POPUP_MENU_SET_BSS_FLAG() -extern const char * popupMenuItems[POPUP_MENU_MAX_LINES]; -extern uint16_t popupMenuNoItems; -extern uint16_t popupMenuOffset; + enum { MENU_OFFSET_INTERNAL, MENU_OFFSET_EXTERNAL }; -extern uint8_t popupMenuOffsetType; -extern uint8_t s_menu_item; -const char * runPopupMenu(event_t event); -extern void (*popupMenuHandler)(const char * result); + +#include "../common/stdlcd/popups.h" #endif // _POPUPS_H_ diff --git a/radio/src/gui/212x64/radio_hardware.cpp b/radio/src/gui/212x64/radio_hardware.cpp index c67501d18..d3e86a989 100644 --- a/radio/src/gui/212x64/radio_hardware.cpp +++ b/radio/src/gui/212x64/radio_hardware.cpp @@ -243,7 +243,7 @@ void menuRadioHardware(event_t event) lcdDrawTextAlignedLeft(y, STR_DEBUG); lcdDrawText(HW_SETTINGS_COLUMN , y, STR_ANALOGS_BTN, menuHorizontalPosition == 0 ? attr : 0); - lcdDrawText(lcdLastRightPos + 2, y, STR_SWITCHES_BTN, menuHorizontalPosition == 1 ? attr : 0); + lcdDrawText(lcdLastRightPos + 2, y, STR_KEYS_BTN, menuHorizontalPosition == 1 ? attr : 0); if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { if (menuHorizontalPosition == 0) pushMenu(menuRadioDiagAnalogs); diff --git a/radio/src/gui/212x64/radio_setup.cpp b/radio/src/gui/212x64/radio_setup.cpp index cce07e5cf..684ba39af 100644 --- a/radio/src/gui/212x64/radio_setup.cpp +++ b/radio/src/gui/212x64/radio_setup.cpp @@ -460,7 +460,7 @@ void menuRadioSetup(event_t event) if (g_eeGeneral.fai) POPUP_WARNING("FAI\001mode blocked!"); else - POPUP_CONFIRMATION("FAI mode?"); + POPUP_CONFIRMATION("FAI mode?", nullptr); } break; #endif diff --git a/radio/src/gui/212x64/radio_version.cpp b/radio/src/gui/212x64/radio_version.cpp index fb864c11a..b3fbaca32 100644 --- a/radio/src/gui/212x64/radio_version.cpp +++ b/radio/src/gui/212x64/radio_version.cpp @@ -38,14 +38,14 @@ void menuRadioVersion(event_t event) lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+4*FH+1, "UID\037\033:"); lcdDrawText(5*FW+3, MENU_HEADER_HEIGHT+4*FH+1, id); - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+5*FH+1, STR_EEBACKUP); - lcdDrawTextAlignedLeft(MENU_HEADER_HEIGHT+6*FH+1, STR_FACTORYRESET); + lcdDrawText(INDENT_WIDTH, MENU_HEADER_HEIGHT+5*FH+1, "[ENTER Long] " STR_EEBACKUP); + lcdDrawText(INDENT_WIDTH, MENU_HEADER_HEIGHT+6*FH+1, "[MENU Long] " STR_FACTORYRESET); lcdDrawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID); if (event == EVT_KEY_LONG(KEY_ENTER)) { eepromBackup(); } else if (event == EVT_KEY_LONG(KEY_MENU)) { - POPUP_CONFIRMATION(STR_CONFIRMRESET); + POPUP_CONFIRMATION(STR_CONFIRMRESET, nullptr); } } diff --git a/radio/src/gui/212x64/view_statistics.cpp b/radio/src/gui/212x64/view_statistics.cpp index e980092be..191a4a95b 100644 --- a/radio/src/gui/212x64/view_statistics.cpp +++ b/radio/src/gui/212x64/view_statistics.cpp @@ -149,7 +149,7 @@ void menuStatisticsDebug(event_t event) #if defined(WATCHDOG_TEST) case EVT_KEY_LONG(KEY_MENU): { - POPUP_CONFIRMATION("Test the watchdog?"); + POPUP_CONFIRMATION("Test the watchdog?", nullptr); const char * w = "The radio will reset!"; SET_WARNING_INFO(w, strlen(w), 0); } diff --git a/radio/src/gui/212x64/widgets.cpp b/radio/src/gui/212x64/widgets.cpp index 8eb631d09..2cfd11b0b 100644 --- a/radio/src/gui/212x64/widgets.cpp +++ b/radio/src/gui/212x64/widgets.cpp @@ -98,22 +98,6 @@ void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uin lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE); } -void drawProgressBar(const char * label, int num, int den) -{ - lcdClear(); - if (label) { - lcdDrawTextAlignedLeft(4*FH, label); - } - lcdDrawRect(4, 6*FH+4, LCD_W-8, 7); - if (num > 0 && den > 0) { - int width = ((LCD_W-12)*num)/den; - lcdDrawSolidHorizontalLine(6, 6*FH+6, width, FORCE); - lcdDrawSolidHorizontalLine(6, 6*FH+7, width, FORCE); - lcdDrawSolidHorizontalLine(6, 6*FH+8, width, FORCE); - } - lcdRefresh(); -} - void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) { lcdDrawRect(x, y, w+1, h); @@ -134,7 +118,7 @@ choice_t editChoice(coord_t x, coord_t y, const char * label, const char *values { drawFieldLabel(x, y, label); if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); - if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); + if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); return value; } diff --git a/radio/src/gui/480x272/bitmapbuffer.cpp b/radio/src/gui/480x272/bitmapbuffer.cpp index 67fb457e4..ae38a8500 100644 --- a/radio/src/gui/480x272/bitmapbuffer.cpp +++ b/radio/src/gui/480x272/bitmapbuffer.cpp @@ -387,7 +387,7 @@ void BitmapBuffer::drawSizedText(coord_t x, coord_t y, const char * s, uint8_t l #if defined(BOOT) unsigned char c = *s; #else - unsigned char c = (flags & ZCHAR) ? idx2char(*s) : *s; + unsigned char c = (flags & ZCHAR) ? zchar2char(*s) : *s; #endif if (setpos) { pos = c; diff --git a/radio/src/gui/480x272/gui.h b/radio/src/gui/480x272/gui.h index 7eac8f04d..38e683b22 100644 --- a/radio/src/gui/480x272/gui.h +++ b/radio/src/gui/480x272/gui.h @@ -62,7 +62,6 @@ #define DATETIME_MIDDLE (LCD_W+DATETIME_SEPARATOR_X+4)/2 #define MENU_TITLE_NEXT_POS (lcdNextPos + 10) -#define MENU_INIT_VPOS -1 #if defined(HELI) && defined(GVARS) && defined(LUA_MODEL_SCRIPTS) #define MENU_ICONS_SPACING 31 diff --git a/radio/src/gui/480x272/lcd.cpp b/radio/src/gui/480x272/lcd.cpp index 3d5fae358..a9f9075ab 100644 --- a/radio/src/gui/480x272/lcd.cpp +++ b/radio/src/gui/480x272/lcd.cpp @@ -130,7 +130,7 @@ int getTextWidth(const char * s, int len, LcdFlags flags) for (int i=0; len==0 || i 0) { int8_t c = name[editNameCursorPos]; if (!(flags & ZCHAR)) { - c = char2idx(c); + c = char2zchar(c); } int8_t v = c; @@ -132,15 +132,15 @@ void editName(coord_t x, coord_t y, char * name, uint8_t size, event_t event, ui if (c != v) { if (!(flags & ZCHAR)) { if (v != '\0' || name[editNameCursorPos+1] != '\0') - v = idx2char(v); + v = zchar2char(v); } name[editNameCursorPos] = v; - storageDirty(menuVerticalPositions[0] == 0 ? EE_MODEL : EE_GENERAL); + storageDirty(isModelMenuDisplayed() ? EE_MODEL : EE_GENERAL); } lcdDrawSizedText(x, y, name, size, flags); coord_t left = (editNameCursorPos == 0 ? 0 : getTextWidth(name, editNameCursorPos, flags)); - char s[] = { (flags & ZCHAR) ? idx2char(name[editNameCursorPos]) : name[editNameCursorPos], '\0' }; + char s[] = { (flags & ZCHAR) ? zchar2char(name[editNameCursorPos]) : name[editNameCursorPos], '\0' }; lcdDrawSolidFilledRect(x+left-1, y, getTextWidth(s, 1)+1, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR); lcdDrawText(x+left, y, s, TEXT_INVERTED_COLOR); } diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index 6aafa5036..a3d3d66f4 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -48,13 +48,20 @@ extern uint8_t menuVerticalPositions[4]; extern uint8_t menuLevel; extern event_t menuEvent; -/// goto given Menu, but substitute current menu in menuStack void chainMenu(MenuHandlerFunc newMenu); -/// goto given Menu, store current menu in menuStack void pushMenu(MenuHandlerFunc newMenu); -/// return to last menu in menuStack void popMenu(); +inline bool isRadioMenuDisplayed() +{ + return menuVerticalPositions[0] == 1; +} + +inline bool isModelMenuDisplayed() +{ + return menuVerticalPositions[0] == 0; +} + enum MenuIcons { ICON_OPENTX, ICON_RADIO, @@ -258,7 +265,6 @@ typedef uint16_t FlightModesType; extern int8_t checkIncDec_Ret; // global helper vars -#define EDIT_SELECT_MENU -1 #define EDIT_SELECT_FIELD 0 #define EDIT_MODIFY_FIELD 1 #define EDIT_MODIFY_STRING 2 @@ -274,7 +280,8 @@ extern int8_t s_editMode; // global editmode #define NO_DBLKEYS 0x80 // mawrow special values -#define TITLE_ROW ((uint8_t)-1) +#define READONLY_ROW ((uint8_t)-1) +#define TITLE_ROW READONLY_ROW #define ORPHAN_ROW ((uint8_t)-2) #define HIDDEN_ROW ((uint8_t)-3) #define NAVIGATION_LINE_BY_LINE 0x40 @@ -469,28 +476,25 @@ void showMessageBox(const char * title); void runPopupWarning(event_t event); extern void (* popupFunc)(event_t event); -extern int16_t warningInputValue; -extern int16_t warningInputValueMin; -extern int16_t warningInputValueMax; extern uint8_t warningInfoFlags; #define DISPLAY_WARNING (*popupFunc) + +#define POPUP_INFORMATION(s) (warningText = s, warningType = WARNING_TYPE_INFO, warningInfoText = 0, popupFunc = runPopupWarning) #define POPUP_WARNING(s) (warningType = WARNING_TYPE_ASTERISK, warningText = s, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_CONFIRMATION(s) (warningText = s, warningType = WARNING_TYPE_CONFIRM, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_INPUT(s, func, start, min, max) (warningText = s, warningType = WARNING_TYPE_INPUT, popupFunc = func, warningInputValue = start, warningInputValueMin = min, warningInputValueMax = max) +#define POPUP_INPUT(s, func) (warningText = s, popupFunc = func) #define WARNING_INFO_FLAGS warningInfoFlags #define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags) -#define NAVIGATION_MENUS -#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuNoItems < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuNoItems++] = s; } while (0) -#define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuNoItems ? s : popupMenuNoItems) : 0) +#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuItemsCount++] = s; } while (0) +#define POPUP_MENU_SELECT_ITEM(s) s_menu_item = (s > 0 ? (s < popupMenuItemsCount ? s : popupMenuItemsCount) : 0) #define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while(0) #define POPUP_MENU_MAX_LINES 12 #define MENU_MAX_DISPLAY_LINES 9 #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) #define POPUP_MENU_SET_BSS_FLAG() extern const char * popupMenuItems[POPUP_MENU_MAX_LINES]; -extern uint16_t popupMenuNoItems; +extern uint16_t popupMenuItemsCount; extern uint16_t popupMenuOffset; enum { MENU_OFFSET_INTERNAL, @@ -501,6 +505,15 @@ extern uint8_t s_menu_item; const char * runPopupMenu(event_t event); extern void (*popupMenuHandler)(const char * result); +inline void POPUP_CONFIRMATION(const char *s, void (* confirmHandler)(const char *) = nullptr) +{ + warningText = s; + warningType = WARNING_TYPE_CONFIRM; + warningInfoText = nullptr; + popupFunc = runPopupWarning; + popupMenuHandler = confirmHandler; +} + #define TEXT_FILENAME_MAXLEN 40 extern char s_text_file[TEXT_FILENAME_MAXLEN]; void pushMenuTextView(const char * filename); diff --git a/radio/src/gui/480x272/model_curves.cpp b/radio/src/gui/480x272/model_curves.cpp index a918585bf..7d15edcaf 100644 --- a/radio/src/gui/480x272/model_curves.cpp +++ b/radio/src/gui/480x272/model_curves.cpp @@ -25,16 +25,36 @@ void drawCurve(int x, int y, int width) drawFunction(applyCurrentCurve, x, y, width); } -void displayPresetChoice(event_t event) +void runPopupCurvePreset(event_t event) { - runPopupWarning(event); - lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y-10, 45*warningInputValue/4, LEFT|INVERS, 0, NULL, "@"); + warningResult = false; + + theme->drawMessageBox(warningText, warningInfoText, STR_POPUPS_ENTER_EXIT, warningType); + + switch (event) { + case EVT_KEY_BREAK(KEY_ENTER): + warningResult = true; + // no break + + case EVT_KEY_BREAK(KEY_EXIT): + warningText = NULL; + warningType = WARNING_TYPE_ASTERISK; + break; + + default: + s_editMode = EDIT_MODIFY_FIELD; + reusableBuffer.curveEdit.preset = checkIncDec(event, reusableBuffer.curveEdit.preset, -4, +4); + s_editMode = EDIT_SELECT_FIELD; + break; + } + + lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y-10, 45 * reusableBuffer.curveEdit.preset / 4, LEFT|INVERS, 0, NULL, "@"); if (warningResult) { warningResult = 0; CurveInfo & crv = g_model.curves[s_curveChan]; int8_t * points = curveAddress(s_curveChan); - int k = 25 * warningInputValue; + int k = 25 * reusableBuffer.curveEdit.preset; int dx = 2000 / (5+crv.points-1); for (uint8_t i=0; i<5+crv.points; i++) { int x = -1000 + i * dx; @@ -49,7 +69,8 @@ void displayPresetChoice(event_t event) void onCurveOneMenu(const char * result) { if (result == STR_CURVE_PRESET) { - POPUP_INPUT(STR_PRESET, displayPresetChoice, 0, -4, 4); + reusableBuffer.curveEdit.preset = 4; // 45° + POPUP_INPUT(STR_PRESET, runPopupCurvePreset); } else if (result == STR_MIRROR) { CurveInfo & crv = g_model.curves[s_curveChan]; diff --git a/radio/src/gui/480x272/model_custom_scripts.cpp b/radio/src/gui/480x272/model_custom_scripts.cpp index b2c0a08b8..96ab0b6ca 100644 --- a/radio/src/gui/480x272/model_custom_scripts.cpp +++ b/radio/src/gui/480x272/model_custom_scripts.cpp @@ -29,7 +29,7 @@ void onModelCustomScriptMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a lua file in the list copySelection(sd.file, result, sizeof(sd.file)); memset(sd.inputs, 0, sizeof(sd.inputs)); diff --git a/radio/src/gui/480x272/model_failsafe.cpp b/radio/src/gui/480x272/model_failsafe.cpp new file mode 100644 index 000000000..bcc04d7a5 --- /dev/null +++ b/radio/src/gui/480x272/model_failsafe.cpp @@ -0,0 +1,138 @@ +/* + * 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. + */ + +#include + +extern uint8_t g_moduleIdx; + +bool menuModelFailsafe(event_t event) +{ + uint8_t ch = 0; + const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + const uint8_t SLIDER_W = 128; + const uint8_t cols = sentModuleChannels(g_moduleIdx) > 8 ? 2 : 1; + + if (event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + event = 0; + + if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { + if (s_editMode) { + g_model.failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; + s_editMode = 0; + } + else { + int16_t & failsafe = g_model.failsafeChannels[menuVerticalPosition]; + if (failsafe < FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_HOLD; + else if (failsafe == FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_NOPULSE; + else + failsafe = 0; + } + } + else { + // "Outputs => Failsafe" menu item + setCustomFailsafe(g_moduleIdx); + } + + storageDirty(EE_MODEL); + AUDIO_WARNING1(); + SEND_FAILSAFE_NOW(g_moduleIdx); + } + + SIMPLE_SUBMENU_WITH_OPTIONS("FAILSAFE", ICON_STATS_ANALOGS, sentModuleChannels(g_moduleIdx)+1, OPTION_MENU_NO_SCROLLBAR); + drawStringWithIndex(50, 3+FH, "Module", g_moduleIdx+1, MENU_TITLE_COLOR); + + for (uint8_t col=0; col < cols; col++) { + for (uint8_t line=0; line < 8; line++) { + coord_t x = col*(LCD_W/2); + const coord_t y = MENU_CONTENT_TOP - FH + line*(FH+2); + const int32_t channelValue = channelOutputs[ch+channelStart]; + int32_t failsafeValue = g_model.failsafeChannels[8*col+line]; + + // Channel name if present, number if not + if (g_model.limitData[ch+channelStart].name[0] != '\0') { + putsChn(x+MENUS_MARGIN_LEFT, y-3, ch+1, TINSIZE); + lcdDrawSizedText(x+MENUS_MARGIN_LEFT, y+5, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR|SMLSIZE); + } + else { + putsChn(x+MENUS_MARGIN_LEFT, y, ch+1, 0); + } + + // Value + LcdFlags flags = RIGHT; + if (menuVerticalPosition == ch) { + flags |= INVERS; + if (s_editMode) { + if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + s_editMode = 0; + } + else { + flags |= BLINK; + CHECK_INCDEC_MODELVAR(event, g_model.failsafeChannels[8*col+line], -lim, +lim); + } + } + } + + x += (LCD_W/2)-4-MENUS_MARGIN_LEFT-SLIDER_W; + + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + lcdDrawText(x, y+2, "HOLD", flags|SMLSIZE); + failsafeValue = 0; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + lcdDrawText(x, y+2, "NONE", flags|SMLSIZE); + failsafeValue = 0; + } + else { +#if defined(PPM_UNIT_US) + lcdDrawNumber(x, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags); +#elif defined(PPM_UNIT_PERCENT_PREC1) + lcdDrawNumber(x, y, calcRESXto1000(failsafeValue), PREC1|flags); +#else + lcdDrawNumber(x, y, calcRESXto1000(failsafeValue)/10, flags); +#endif + } + + // Gauge + x += 4; + lcdDrawRect(x, y+3, SLIDER_W+1, 12); + const coord_t lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2)); + const coord_t lenFailsafe = limit((uint8_t)1, uint8_t((abs(failsafeValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2)); + x += SLIDER_W/2; + const coord_t xChannel = (channelValue>0) ? x : x+1-lenChannel; + const coord_t xFailsafe = (failsafeValue>0) ? x : x+1-lenFailsafe; + lcdDrawSolidFilledRect(xChannel, y+4, lenChannel, 5, TEXT_COLOR); + lcdDrawSolidFilledRect(xFailsafe, y+9, lenFailsafe, 5, ALARM_COLOR); + + if (++ch >= sentModuleChannels(g_moduleIdx)) { + + // draw that menu at the bottom center + flags = CENTERED | (menuVerticalPosition == ch ? INVERS : 0); + lcdDrawSizedText(LCD_W/2, MENU_CONTENT_TOP - FH + 8*(FH+2), STR_OUTPUTS2FAILSAFE, 20, flags); + break; + } + } + } + + return true; +} diff --git a/radio/src/gui/480x272/model_module_options.cpp b/radio/src/gui/480x272/model_module_options.cpp new file mode 100644 index 000000000..f72d3594f --- /dev/null +++ b/radio/src/gui/480x272/model_module_options.cpp @@ -0,0 +1,21 @@ +/* + * 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. + */ + +#include diff --git a/radio/src/gui/480x272/model_receiver_options.cpp b/radio/src/gui/480x272/model_receiver_options.cpp new file mode 100644 index 000000000..f72d3594f --- /dev/null +++ b/radio/src/gui/480x272/model_receiver_options.cpp @@ -0,0 +1,21 @@ +/* + * 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. + */ + +#include diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 0931e475b..1311235ea 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -82,6 +82,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND, #endif ITEM_MODEL_EXTERNAL_MODULE_POWER, + ITEM_MODEL_EXTERNAL_MODULE_FREQ, ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, ITEM_MODEL_TRAINER_LINE1, @@ -97,18 +98,21 @@ enum MenuModelSetupItems { #define MODEL_SETUP_SET_FAILSAFE_OFS 100 #define MODEL_SETUP_SLIDPOT_SPACING 45 -#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) +#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) void checkModelIdUnique(uint8_t moduleIdx) { - char* warn_buf = reusableBuffer.modelsetup.msg; + if(isModulePXX(moduleIdx) && IS_D8_RX(moduleIdx)) + return; + + char* warn_buf = reusableBuffer.moduleSetup.msg; // cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 - size_t warn_buf_len = sizeof(reusableBuffer.modelsetup.msg) - WARNING_LINE_LEN - 2; + size_t warn_buf_len = sizeof(reusableBuffer.moduleSetup.msg) - WARNING_LINE_LEN - 2; if (!modelslist.isModelIdUnique(moduleIdx,warn_buf,warn_buf_len)) { if (warn_buf[0] != 0) { POPUP_WARNING(STR_MODELIDUSED); - SET_WARNING_INFO(warn_buf, sizeof(reusableBuffer.modelsetup.msg), 0); + SET_WARNING_INFO(warn_buf, sizeof(reusableBuffer.moduleSetup.msg), 0); } } } @@ -137,7 +141,7 @@ void onBindMenu(const char * result) return; } - moduleFlag[moduleIdx] = MODULE_BIND; + moduleSettings[moduleIdx].mode = MODULE_MODE_BIND; } void onModelSetupBitmapMenu(const char * result) @@ -147,7 +151,7 @@ void onModelSetupBitmapMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a bmp file in the list copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); storageDirty(EE_MODEL); @@ -231,12 +235,12 @@ int getSwitchWarningsCount() #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) #define INTERNAL_MODULE_MODE_ROWS (uint8_t)0 -#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(1) #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) #define TIMER_ROWS(x) NAVIGATION_LINE_BY_LINE|1, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 : (uint8_t)0 -#define EXTERNAL_MODULE_MODE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : isModuleMultimodule(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0 +#define EXTERNAL_MODULE_MODE_ROWS (isModuleXJT(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 +#define EXTRA_MODULE_ROWS isR9MMFlex(EXTERNAL_MODULE) ? (uint8_t)1: (uint8_t)HIDDEN_ROW, #if TIMERS == 1 #define TIMERS_ROWS TIMER_ROWS(0) @@ -252,8 +256,8 @@ int getSwitchWarningsCount() #define SLIDER_WARN_ITEMS() ((g_model.potsWarnMode) ? uint8_t(NAVIGATION_LINE_BY_LINE|(NUM_SLIDERS-1)) : (uint8_t)0) #define TRAINER_LINE1_BLUETOOTH_M_ROWS ((bluetoothDistantAddr[0] == 0 || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) -#define TRAINER_LINE1_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)1 : (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_LINE1_BLUETOOTH_M_ROWS : (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH ? (uint8_t)1 : HIDDEN_ROW))) -#define TRAINER_LINE2_ROWS (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) +#define TRAINER_LINE1_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)1 : (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_LINE1_BLUETOOTH_M_ROWS : (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH ? (uint8_t)1 : HIDDEN_ROW))) +#define TRAINER_LINE2_ROWS (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) bool menuModelSetup(event_t event) { @@ -285,18 +289,19 @@ bool menuModelSetup(event_t event) EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, + EXTRA_MODULE_ROWS LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS }); if (event == EVT_ENTRY) { - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; } if (menuEvent) { - moduleFlag[0] = 0; - moduleFlag[1] = 0; + moduleSettings[0].mode = 0; + moduleSettings[1].mode = 0; } int sub = menuVerticalPosition; @@ -675,7 +680,7 @@ bool menuModelSetup(event_t event) case ITEM_MODEL_TRAINER_MODE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODE); - g_model.trainerMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, 0, TRAINER_MODE_MAX(), attr, event); + g_model.trainerData.mode = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), attr, event); if (attr && checkIncDec_Ret) { bluetoothState = BLUETOOTH_STATE_OFF; bluetoothDistantAddr[0] = 0; @@ -693,8 +698,8 @@ bool menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0)); else if (isModuleDSM2(EXTERNAL_MODULE)) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0)); - else if (isModuleR9M(EXTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0)); + else if (isR9ModuleRunning(EXTERNAL_MODULE)) + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].r9m.region, (menuHorizontalPosition==1 ? attr : 0)); #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -714,7 +719,9 @@ bool menuModelSetup(event_t event) if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: - g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable); + g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, + MODULE_TYPE_NONE, MODULE_TYPE_COUNT - 1, EE_MODEL, + isExternalModuleAvailable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; @@ -728,15 +735,6 @@ bool menuModelSetup(event_t event) case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); - else if (isModuleR9M(EXTERNAL_MODULE)) { - uint8_t newR9MType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LAST, EE_MODEL, isR9MModeAvailable); - if (newR9MType != g_model.moduleData[EXTERNAL_MODULE].subType && newR9MType > MODULE_SUBTYPE_R9M_EU) { - POPUP_WARNING(STR_R9MFLEXWARN1); - const char * w = STR_R9MFLEXWARN2; - SET_WARNING_INFO(w, strlen(w), 0); - } - g_model.moduleData[EXTERNAL_MODULE].subType = newR9MType; - } #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); @@ -790,7 +788,7 @@ bool menuModelSetup(event_t event) break; case ITEM_MODEL_TRAINER_LINE1: - if (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH) { + if (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH) { if (attr) { s_editMode = 0; } @@ -864,9 +862,28 @@ bool menuModelSetup(event_t event) break; } + case ITEM_MODEL_TRAINER_LINE2: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_PPMFRAME); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)g_model.trainerData.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT, 0, NULL, STR_MS); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+80, y, (g_model.trainerData.delay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr|LEFT : LEFT, 0, NULL, "us"); + lcdDrawText(MODEL_SETUP_2ND_COLUMN+160, y, g_model.trainerData.pulsePol ? "+" : "-", (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0); + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.frameLength, -20, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.trainerData.delay, -4, 10); + break; + case 2: + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.trainerData.pulsePol, 1); + break; + } + } + break; + case ITEM_MODEL_INTERNAL_MODULE_BIND: case ITEM_MODEL_EXTERNAL_MODULE_BIND: - case ITEM_MODEL_TRAINER_LINE2: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; @@ -932,8 +949,8 @@ bool menuModelSetup(event_t event) } } } - drawButton(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, (moduleFlag[moduleIdx] == MODULE_BIND ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==1 ? attr : 0)); - drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, (moduleFlag[moduleIdx] == MODULE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0)); + drawButton(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==1 ? attr : 0)); + drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, (moduleSettings[moduleIdx].mode == MODULE_MODE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0)); uint8_t newFlag = 0; #if defined(MULTIMODULE) if (multiBindStatus == MULTI_BIND_FINISHED) { @@ -969,27 +986,27 @@ bool menuModelSetup(event_t event) POPUP_MENU_START(onBindMenu); continue; } - if (moduleFlag[moduleIdx] == MODULE_BIND) { - newFlag = MODULE_BIND; + if (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND) { + newFlag = MODULE_MODE_BIND; } else { - if (!popupMenuNoItems) { + if (!popupMenuItemsCount) { s_editMode = 0; // this is when popup is exited before a choice is made } } } else { - newFlag = MODULE_BIND; + newFlag = MODULE_MODE_BIND; } } else if (l_posHorz == 2) { - newFlag = MODULE_RANGECHECK; + newFlag = MODULE_MODE_RANGECHECK; } } } - moduleFlag[moduleIdx] = newFlag; + moduleSettings[moduleIdx].mode = newFlag; #if defined(MULTIMODULE) - if (newFlag == MODULE_BIND) + if (newFlag == MODULE_MODE_BIND) multiBindStatus = MULTI_BIND_INITIATED; #endif } @@ -1068,16 +1085,7 @@ bool menuModelSetup(event_t event) } } #endif - if (isModuleR9M(moduleIdx)) { - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODULE_TELEMETRY); - if (IS_TELEMETRY_INTERNAL_MODULE()) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL); - } - else { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON); - } - } - else if (isModuleSBUS(moduleIdx)) { + if (isModuleSBUS(moduleIdx)) { lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WARN_BATTVOLTAGE); drawValueWithUnit(MODEL_SETUP_4TH_COLUMN, y, getBatteryVoltage(), UNIT_VOLTS, attr|PREC2|LEFT); } @@ -1098,12 +1106,12 @@ bool menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_LBT_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr); if (attr) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, R9M_LBT_POWER_MAX); - if (attr && s_editMode == 0 && reusableBuffer.modelsetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { - if((reusableBuffer.modelsetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) { //switching between mode 2 and 3 does not require rebind + if (attr && s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != g_model.moduleData[moduleIdx].pxx.power) { + if((reusableBuffer.moduleSetup.r9mPower + g_model.moduleData[moduleIdx].pxx.power) < 5) { //switching between mode 2 and 3 does not require rebind POPUP_WARNING(STR_WARNING); SET_WARNING_INFO(STR_REBIND, sizeof(TR_REBIND), 0); } - reusableBuffer.modelsetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[moduleIdx].pxx.power; } } } @@ -1116,6 +1124,18 @@ bool menuModelSetup(event_t event) } break; + case ITEM_MODEL_EXTERNAL_MODULE_FREQ: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_FREQUENCY); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9MFLEX_FREQ, g_model.moduleData[moduleIdx].r9m.freq, LEFT | attr); + if (attr) + { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[moduleIdx].r9m.freq, 1); + } + } + break; + #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) @@ -1180,118 +1200,3 @@ bool menuModelSetup(event_t event) return true; } - -bool menuModelFailsafe(event_t event) -{ - uint8_t ch = 0; - const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; - const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; - const uint8_t SLIDER_W = 128; - const uint8_t cols = sentModuleChannels(g_moduleIdx) > 8 ? 2 : 1; - - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - event = 0; - - if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { - if (s_editMode) { - g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; - s_editMode = 0; - } - else { - int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition]; - if (failsafe < FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_HOLD; - else if (failsafe == FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_NOPULSE; - else - failsafe = 0; - } - } - else { - // "Outputs => Failsafe" menu item - setCustomFailsafe(g_moduleIdx); - } - - storageDirty(EE_MODEL); - AUDIO_WARNING1(); - SEND_FAILSAFE_NOW(g_moduleIdx); - } - - SIMPLE_SUBMENU_WITH_OPTIONS("FAILSAFE", ICON_STATS_ANALOGS, sentModuleChannels(g_moduleIdx)+1, OPTION_MENU_NO_SCROLLBAR); - drawStringWithIndex(50, 3+FH, "Module", g_moduleIdx+1, MENU_TITLE_COLOR); - - for (uint8_t col=0; col < cols; col++) { - for (uint8_t line=0; line < 8; line++) { - coord_t x = col*(LCD_W/2); - const coord_t y = MENU_CONTENT_TOP - FH + line*(FH+2); - const int32_t channelValue = channelOutputs[ch+channelStart]; - int32_t failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; - - // Channel name if present, number if not - if (g_model.limitData[ch+channelStart].name[0] != '\0') { - putsChn(x+MENUS_MARGIN_LEFT, y-3, ch+1, TINSIZE); - lcdDrawSizedText(x+MENUS_MARGIN_LEFT, y+5, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR|SMLSIZE); - } - else { - putsChn(x+MENUS_MARGIN_LEFT, y, ch+1, 0); - } - - // Value - LcdFlags flags = RIGHT; - if (menuVerticalPosition == ch) { - flags |= INVERS; - if (s_editMode) { - if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - s_editMode = 0; - } - else { - flags |= BLINK; - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line], -lim, +lim); - } - } - } - - x += (LCD_W/2)-4-MENUS_MARGIN_LEFT-SLIDER_W; - - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - lcdDrawText(x, y+2, "HOLD", flags|SMLSIZE); - failsafeValue = 0; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - lcdDrawText(x, y+2, "NONE", flags|SMLSIZE); - failsafeValue = 0; - } - else { -#if defined(PPM_UNIT_US) - lcdDrawNumber(x, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags); -#elif defined(PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(x, y, calcRESXto1000(failsafeValue), PREC1|flags); -#else - lcdDrawNumber(x, y, calcRESXto1000(failsafeValue)/10, flags); -#endif - } - - // Gauge - x += 4; - lcdDrawRect(x, y+3, SLIDER_W+1, 12); - const coord_t lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2)); - const coord_t lenFailsafe = limit((uint8_t)1, uint8_t((abs(failsafeValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2)); - x += SLIDER_W/2; - const coord_t xChannel = (channelValue>0) ? x : x+1-lenChannel; - const coord_t xFailsafe = (failsafeValue>0) ? x : x+1-lenFailsafe; - lcdDrawSolidFilledRect(xChannel, y+4, lenChannel, 5, TEXT_COLOR); - lcdDrawSolidFilledRect(xFailsafe, y+9, lenFailsafe, 5, ALARM_COLOR); - - if (++ch >= sentModuleChannels(g_moduleIdx)) { - - // draw that menu at the bottom center - flags = CENTERED | (menuVerticalPosition == ch ? INVERS : 0); - lcdDrawSizedText(LCD_W/2, MENU_CONTENT_TOP - FH + 8*(FH+2), STR_OUTPUTS2FAILSAFE, 20, flags); - break; - } - } - } - - return true; -} diff --git a/radio/src/gui/480x272/model_special_functions.cpp b/radio/src/gui/480x272/model_special_functions.cpp index 1ed3528d2..7d4d6c46c 100644 --- a/radio/src/gui/480x272/model_special_functions.cpp +++ b/radio/src/gui/480x272/model_special_functions.cpp @@ -56,7 +56,7 @@ void onCustomFunctionsFileSelectionMenu(const char * result) POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); } } - else { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cf->play.name, result, sizeof(cf->play.name)); storageDirty(eeFlags); @@ -128,7 +128,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } diff --git a/radio/src/gui/480x272/model_telemetry.cpp b/radio/src/gui/480x272/model_telemetry.cpp index 5b5b10cbf..e31e6af37 100644 --- a/radio/src/gui/480x272/model_telemetry.cpp +++ b/radio/src/gui/480x272/model_telemetry.cpp @@ -59,6 +59,38 @@ enum MenuModelTelemetryFrskyItems { ITEM_TELEMETRY_SENSOR30, ITEM_TELEMETRY_SENSOR31, ITEM_TELEMETRY_SENSOR32, + ITEM_TELEMETRY_SENSOR33, + ITEM_TELEMETRY_SENSOR34, + ITEM_TELEMETRY_SENSOR35, + ITEM_TELEMETRY_SENSOR36, + ITEM_TELEMETRY_SENSOR37, + ITEM_TELEMETRY_SENSOR38, + ITEM_TELEMETRY_SENSOR39, + ITEM_TELEMETRY_SENSOR40, + ITEM_TELEMETRY_SENSOR41, + ITEM_TELEMETRY_SENSOR42, + ITEM_TELEMETRY_SENSOR43, + ITEM_TELEMETRY_SENSOR44, + ITEM_TELEMETRY_SENSOR45, + ITEM_TELEMETRY_SENSOR46, + ITEM_TELEMETRY_SENSOR47, + ITEM_TELEMETRY_SENSOR48, + ITEM_TELEMETRY_SENSOR49, + ITEM_TELEMETRY_SENSOR50, + ITEM_TELEMETRY_SENSOR51, + ITEM_TELEMETRY_SENSOR52, + ITEM_TELEMETRY_SENSOR53, + ITEM_TELEMETRY_SENSOR54, + ITEM_TELEMETRY_SENSOR55, + ITEM_TELEMETRY_SENSOR56, + ITEM_TELEMETRY_SENSOR57, + ITEM_TELEMETRY_SENSOR58, + ITEM_TELEMETRY_SENSOR59, + ITEM_TELEMETRY_SENSOR60, + ITEM_TELEMETRY_SENSOR61, + ITEM_TELEMETRY_SENSOR62, + ITEM_TELEMETRY_SENSOR63, + ITEM_TELEMETRY_SENSOR64, ITEM_TELEMETRY_DISCOVER_SENSORS, ITEM_TELEMETRY_NEW_SENSOR, ITEM_TELEMETRY_DELETE_ALL_SENSORS, @@ -82,7 +114,8 @@ enum MenuModelTelemetryFrskyItems { #define IS_RANGE_DEFINED(k) (g_model.frsky.channels[k].ratio > 0) #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) -#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), 0, 0, 0, 0, +#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), \ + SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40),SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50),SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59),SENSOR_ROWS(60),SENSOR_ROWS(61), SENSOR_ROWS(62), SENSOR_ROWS(63), 0, 0, 0, 0, #if defined(VARIO) #define VARIO_ROWS LABEL(Vario), 0, 1, 2, #else diff --git a/radio/src/gui/480x272/popups.cpp b/radio/src/gui/480x272/popups.cpp index d26ccff61..147592d3c 100644 --- a/radio/src/gui/480x272/popups.cpp +++ b/radio/src/gui/480x272/popups.cpp @@ -26,13 +26,10 @@ uint8_t warningInfoLength; uint8_t warningType; uint8_t warningResult = 0; uint8_t warningInfoFlags = ZCHAR; -int16_t warningInputValue; -int16_t warningInputValueMin; -int16_t warningInputValueMax; void (*popupFunc)(event_t event) = NULL; const char *popupMenuItems[POPUP_MENU_MAX_LINES]; uint8_t s_menu_item = 0; -uint16_t popupMenuNoItems = 0; +uint16_t popupMenuItemsCount = 0; uint16_t popupMenuOffset = 0; uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL; void (*popupMenuHandler)(const char * result); @@ -80,24 +77,20 @@ void runPopupWarning(event_t event) { warningResult = false; - theme->drawMessageBox(warningText, warningInfoText, warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS, warningType); + theme->drawMessageBox(warningText, warningInfoText, WARNING_TYPE_INFO ? STR_OK : (warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS_ENTER_EXIT), warningType); switch (event) { case EVT_KEY_BREAK(KEY_ENTER): if (warningType == WARNING_TYPE_ASTERISK) break; - warningResult = true; + if (warningType != WARNING_TYPE_INFO) + warningResult = true; // no break + case EVT_KEY_BREAK(KEY_EXIT): warningText = NULL; warningType = WARNING_TYPE_ASTERISK; break; - default: - if (warningType != WARNING_TYPE_INPUT) break; - s_editMode = EDIT_MODIFY_FIELD; - warningInputValue = checkIncDec(event, warningInputValue, warningInputValueMin, warningInputValueMax); - s_editMode = EDIT_SELECT_FIELD; - break; } } @@ -105,7 +98,7 @@ const char * runPopupMenu(event_t event) { const char * result = NULL; - uint8_t display_count = min(popupMenuNoItems, MENU_MAX_DISPLAY_LINES); + uint8_t display_count = min(popupMenuItemsCount, MENU_MAX_DISPLAY_LINES); switch (event) { case EVT_ROTARY_LEFT: @@ -118,18 +111,18 @@ const char * runPopupMenu(event_t event) } else { s_menu_item = min(display_count, MENU_MAX_DISPLAY_LINES) - 1; - if (popupMenuNoItems > MENU_MAX_DISPLAY_LINES) { - popupMenuOffset = popupMenuNoItems - MENU_MAX_DISPLAY_LINES; + if (popupMenuItemsCount > MENU_MAX_DISPLAY_LINES) { + popupMenuOffset = popupMenuItemsCount - MENU_MAX_DISPLAY_LINES; result = STR_UPDATE_LIST; } } break; case EVT_ROTARY_RIGHT: - if (s_menu_item < display_count - 1 && popupMenuOffset + s_menu_item + 1 < popupMenuNoItems) { + if (s_menu_item < display_count - 1 && popupMenuOffset + s_menu_item + 1 < popupMenuItemsCount) { s_menu_item++; } - else if (popupMenuNoItems > popupMenuOffset + display_count) { + else if (popupMenuItemsCount > popupMenuOffset + display_count) { popupMenuOffset++; result = STR_UPDATE_LIST; } @@ -147,7 +140,7 @@ const char * runPopupMenu(event_t event) // no break case EVT_KEY_BREAK(KEY_EXIT): - popupMenuNoItems = 0; + popupMenuItemsCount = 0; s_menu_item = 0; popupMenuOffset = 0; break; @@ -168,8 +161,8 @@ const char * runPopupMenu(event_t event) } } - if (popupMenuNoItems > display_count) { - drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuNoItems, MENU_MAX_DISPLAY_LINES); + if (popupMenuItemsCount > display_count) { + drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuItemsCount, MENU_MAX_DISPLAY_LINES); } return result; diff --git a/radio/src/gui/480x272/radio_sdmanager.cpp b/radio/src/gui/480x272/radio_sdmanager.cpp index 7206687b2..711ffdfb0 100644 --- a/radio/src/gui/480x272/radio_sdmanager.cpp +++ b/radio/src/gui/480x272/radio_sdmanager.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "opentx.h" #include "storage/modelslist.h" @@ -141,15 +142,18 @@ void onSdManagerMenu(const char * result) } else if (result == STR_FLASH_INTERNAL_MODULE) { getSelectionFullPath(lfn); - sportFlashDevice(INTERNAL_MODULE, lfn); + DeviceFirmwareUpdate device(INTERNAL_MODULE); + device.flashFile(lfn); } else if (result == STR_FLASH_EXTERNAL_MODULE) { getSelectionFullPath(lfn); - sportFlashDevice(EXTERNAL_MODULE, lfn); + DeviceFirmwareUpdate device(EXTERNAL_MODULE); + device.flashFile(lfn); } else if (result == STR_FLASH_EXTERNAL_DEVICE) { getSelectionFullPath(lfn); - sportFlashDevice(FLASHING_MODULE, lfn); + DeviceFirmwareUpdate device(SPORT_MODULE); + device.flashFile(lfn); } #if defined(LUA) else if (result == STR_EXECUTE_FILE) { diff --git a/radio/src/gui/480x272/radio_setup.cpp b/radio/src/gui/480x272/radio_setup.cpp index a4e86b44e..9f921fe94 100644 --- a/radio/src/gui/480x272/radio_setup.cpp +++ b/radio/src/gui/480x272/radio_setup.cpp @@ -403,10 +403,12 @@ bool menuRadioSetup(event_t event) g_eeGeneral.gpsFormat = editChoice(RADIO_SETUP_2ND_COLUMN, y, STR_GPSFORMAT, g_eeGeneral.gpsFormat, 0, 1, attr, event); break; +#if defined(PXX) case ITEM_SETUP_COUNTRYCODE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_COUNTRYCODE); g_eeGeneral.countryCode = editChoice(RADIO_SETUP_2ND_COLUMN, y, STR_COUNTRYCODES, g_eeGeneral.countryCode, 0, 2, attr, event); break; +#endif case ITEM_SETUP_LANGUAGE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_VOICELANG); diff --git a/radio/src/gui/480x272/screens_setup.cpp b/radio/src/gui/480x272/screens_setup.cpp index a329a136f..749bd50c2 100644 --- a/radio/src/gui/480x272/screens_setup.cpp +++ b/radio/src/gui/480x272/screens_setup.cpp @@ -53,7 +53,7 @@ void onZoneOptionFileSelectionMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else { + else if (result != STR_EXIT) { fileSelectionDone = true; memcpy(fileSelection, result, sizeof(fileSelection)); } diff --git a/radio/src/gui/480x272/themes/darkblue.cpp b/radio/src/gui/480x272/themes/darkblue.cpp index 24cf4616b..9d2e1cbdb 100644 --- a/radio/src/gui/480x272/themes/darkblue.cpp +++ b/radio/src/gui/480x272/themes/darkblue.cpp @@ -136,12 +136,10 @@ class DarkblueTheme: public Theme delete calibHorus; #if defined(PCBX10) - if(STICKS_PWM_ENABLED()) { + if (STICKS_PWM_ENABLED()) calibHorus = BitmapBuffer::load(getThemePath("X10S.bmp")); - } - else { + else calibHorus = BitmapBuffer::load(getThemePath("X10.bmp")); - } #else calibHorus = BitmapBuffer::load(getThemePath("horus.bmp")); #endif diff --git a/radio/src/gui/480x272/widgets.cpp b/radio/src/gui/480x272/widgets.cpp index 065017c6f..f726b193b 100644 --- a/radio/src/gui/480x272/widgets.cpp +++ b/radio/src/gui/480x272/widgets.cpp @@ -108,12 +108,12 @@ void drawHorizontalScrollbar(coord_t x, coord_t y, coord_t w, uint16_t offset, u } } -void drawProgressBar(const char * label, int num, int den) +void drawProgressScreen(const char * title, const char * message, int num, int den) { lcdClear(); lcdSetColor(WHITE); - if (label) { - lcdDrawText(MENUS_MARGIN_LEFT, LCD_H-42, label, CUSTOM_COLOR); + if (message) { + lcdDrawText(MENUS_MARGIN_LEFT, LCD_H-42, message, CUSTOM_COLOR); } lcdDrawRect(MENUS_MARGIN_LEFT, LCD_H-22, LCD_W-2*MENUS_MARGIN_LEFT, 15, 1, SOLID, CUSTOM_COLOR); lcdSetColor(RED); diff --git a/radio/src/gui/480x272/widgets.h b/radio/src/gui/480x272/widgets.h index 0e2784421..e8be64672 100644 --- a/radio/src/gui/480x272/widgets.h +++ b/radio/src/gui/480x272/widgets.h @@ -49,7 +49,7 @@ void drawButton(coord_t x, coord_t y, const char * label, LcdFlags attr); void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); void drawHorizontalScrollbar(coord_t x, coord_t y, coord_t w, uint16_t offset, uint16_t count, uint8_t visible); -void drawProgressBar(const char * label, int num, int den); +void drawProgressScreen(const char * title, const char * message, int num, int den); void drawShadow(coord_t x, coord_t y, coord_t w, coord_t h); void drawTrimSquare(coord_t x, coord_t y); void drawHorizontalTrimPosition(coord_t x, coord_t y, int16_t dir); diff --git a/radio/src/gui/CMakeLists.txt b/radio/src/gui/CMakeLists.txt index 6ec951c20..0dd24c589 100644 --- a/radio/src/gui/CMakeLists.txt +++ b/radio/src/gui/CMakeLists.txt @@ -9,6 +9,9 @@ set(GUI_SRC menu_model.cpp model_select.cpp model_setup.cpp + model_failsafe.cpp + model_module_options.cpp + model_receiver_options.cpp model_logical_switches.cpp model_special_functions.cpp model_telemetry.cpp diff --git a/radio/src/gui/common/colorlcd/widgets.cpp b/radio/src/gui/common/colorlcd/widgets.cpp index 84f49e67d..0dd0a4a39 100644 --- a/radio/src/gui/common/colorlcd/widgets.cpp +++ b/radio/src/gui/common/colorlcd/widgets.cpp @@ -46,7 +46,7 @@ void drawValueWithUnit(coord_t x, coord_t y, int32_t val, uint8_t unit, LcdFlags int editChoice(coord_t x, coord_t y, const char * values, int value, int min, int max, LcdFlags attr, event_t event) { - if (attr & INVERS) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); + if (attr & INVERS) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); return value; } diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index a9056719f..26e29bbda 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -28,5 +28,15 @@ if(SDCARD) set(GUI_SRC ${GUI_SRC} ../common/stdlcd/radio_sdmanager.cpp + ../common/stdlcd/radio_tools.cpp ) endif() + +if(PXX2) + set(GUI_SRC + ${GUI_SRC} + ../common/stdlcd/radio_spectrum_analyser.cpp + ../common/stdlcd/radio_power_meter.cpp + ) +endif() + diff --git a/radio/src/gui/common/stdlcd/popups.cpp b/radio/src/gui/common/stdlcd/popups.cpp index abd7890da..e4dfe0e5f 100644 --- a/radio/src/gui/common/stdlcd/popups.cpp +++ b/radio/src/gui/common/stdlcd/popups.cpp @@ -20,33 +20,77 @@ #include "opentx.h" -uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL; -void (*popupFunc)(event_t event) = NULL; +const char * warningText = NULL; +const char * warningInfoText; +uint8_t warningInfoLength; +uint8_t warningType; +uint8_t warningResult = 0; +uint8_t warningInfoFlags = ZCHAR; + +uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL; +void (* popupFunc)(event_t event) = NULL; -#if defined(NAVIGATION_MENUS) const char * popupMenuItems[POPUP_MENU_MAX_LINES]; -uint8_t s_menu_item = 0; -uint16_t popupMenuNoItems = 0; -uint8_t popupMenuFlags = 0; -uint16_t popupMenuOffset = 0; -void (*popupMenuHandler)(const char * result); +uint8_t s_menu_item = 0; +uint16_t popupMenuItemsCount = 0; +uint16_t popupMenuOffset = 0; +void (* popupMenuHandler)(const char * result); +const char * popupMenuTitle = nullptr; + +void drawMessageBoxBackground(coord_t top, coord_t height) +{ + // white background + lcdDrawFilledRect(MESSAGEBOX_X - 1, top - 1, MESSAGEBOX_W + 2, height + 2, SOLID, ERASE); + + // border + lcdDrawRect(MESSAGEBOX_X, top, MESSAGEBOX_W, height, SOLID, FORCE); +} + +void drawMessageBox(const char * title) +{ + // background + border + drawMessageBoxBackground(MESSAGEBOX_Y, 40); + + // title + lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y, title, WARNING_LINE_LEN); + + // could be a place for a warningInfoText +} + +void showMessageBox(const char * title) +{ + drawMessageBox(title); + lcdRefresh(); +} const char * runPopupMenu(event_t event) { - const char * result = NULL; + const char * result = nullptr; - uint8_t display_count = min(popupMenuNoItems, MENU_MAX_DISPLAY_LINES); - uint8_t y = (display_count >= 5 ? MENU_Y - FH - 1 : MENU_Y); - lcdDrawFilledRect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE); - lcdDrawRect(MENU_X, y, MENU_W, display_count * (FH+1) + 2); + uint8_t display_count = min(popupMenuItemsCount, MENU_MAX_DISPLAY_LINES); + uint8_t y = LCD_H / 2 - (popupMenuTitle ? 0 : 3) - (display_count * FH / 2); + // white background + lcdDrawFilledRect(MENU_X - 1, popupMenuTitle ? y - FH - 3 : y - 1, MENU_W + 2, display_count * (FH + 1) + (popupMenuTitle ? FH + 6 : 4), SOLID, ERASE); + + // title + if (popupMenuTitle) { + lcdDrawText(MENU_X + 2, y - FH, popupMenuTitle, BOLD); + lcdDrawRect(MENU_X, y - FH - 2, lcdLastRightPos - MENU_X + 2, FH + 3); + } + + // border + lcdDrawRect(MENU_X, y, MENU_W, display_count * (FH + 1) + 2, SOLID, FORCE); + + // items for (uint8_t i=0; i display_count) { - drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuNoItems, display_count); + // scrollbar + if (popupMenuItemsCount > display_count) { + drawVerticalScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_DISPLAY_LINES * (FH+1), popupMenuOffset, popupMenuItemsCount, display_count); } switch (event) { @@ -67,8 +111,8 @@ const char * runPopupMenu(event_t event) else { s_menu_item = min(display_count, MENU_MAX_DISPLAY_LINES) - 1; #if defined(SDCARD) - if (popupMenuNoItems > MENU_MAX_DISPLAY_LINES) { - popupMenuOffset = popupMenuNoItems - display_count; + if (popupMenuItemsCount > MENU_MAX_DISPLAY_LINES) { + popupMenuOffset = popupMenuItemsCount - display_count; result = STR_UPDATE_LIST; } #endif @@ -80,11 +124,11 @@ const char * runPopupMenu(event_t event) #endif case EVT_KEY_FIRST(KEY_DOWN): case EVT_KEY_REPT(KEY_DOWN): - if (s_menu_item < display_count - 1 && popupMenuOffset + s_menu_item + 1 < popupMenuNoItems) { + if (s_menu_item < display_count - 1 && popupMenuOffset + s_menu_item + 1 < popupMenuItemsCount) { s_menu_item++; } #if defined(SDCARD) - else if (popupMenuNoItems > popupMenuOffset + display_count) { + else if (popupMenuItemsCount > popupMenuOffset + display_count) { popupMenuOffset++; result = STR_UPDATE_LIST; } @@ -105,7 +149,11 @@ const char * runPopupMenu(event_t event) #endif case EVT_KEY_BREAK(KEY_ENTER): result = popupMenuItems[s_menu_item + (popupMenuOffsetType == MENU_OFFSET_INTERNAL ? popupMenuOffset : 0)]; - // no break + popupMenuItemsCount = 0; + s_menu_item = 0; + popupMenuOffset = 0; + popupMenuTitle = nullptr; + break; #if defined(CASE_EVT_ROTARY_LONG) CASE_EVT_ROTARY_LONG @@ -114,13 +162,83 @@ const char * runPopupMenu(event_t event) #endif case EVT_KEY_BREAK(KEY_EXIT): - popupMenuNoItems = 0; + result = STR_EXIT; + popupMenuItemsCount = 0; s_menu_item = 0; - popupMenuFlags = 0; popupMenuOffset = 0; + popupMenuTitle = nullptr; break; } return result; } -#endif + +void runPopupWarning(event_t event) +{ + warningResult = false; + + drawMessageBox(warningText); + + if (warningInfoText) { + lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+FH, warningInfoText, warningInfoLength, WARNING_INFO_FLAGS); + } + + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+2*FH, warningType == WARNING_TYPE_INFO ? STR_OK : (warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS_ENTER_EXIT)); + + switch (event) { + case EVT_KEY_BREAK(KEY_ENTER): + if (warningType == WARNING_TYPE_ASTERISK) + // key ignored, the user has to press [EXIT] + break; + + if (warningType == WARNING_TYPE_CONFIRM) { + warningType = WARNING_TYPE_ASTERISK; + warningText = nullptr; + if (popupMenuHandler) + popupMenuHandler(STR_OK); + else + warningResult = true; + break; + } + // no break + + case EVT_KEY_BREAK(KEY_EXIT): + if (warningType == WARNING_TYPE_CONFIRM) { + if (popupMenuHandler) + popupMenuHandler(STR_EXIT); + } + warningText = nullptr; + warningType = WARNING_TYPE_ASTERISK; + break; + } +} + +void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound) +{ + drawAlertBox(title, text, action); + AUDIO_ERROR_MESSAGE(sound); + lcdRefresh(); + lcdSetContrast(); + clearKeyEvents(); + backlightOn(); + checkBacklight(); +} + +void drawProgressScreen(const char * title, const char * message, int num, int den) +{ + lcdClear(); + if (title) { + lcdDrawText(LCD_W / 2 - getTextWidth(title) / 2, 2*FH, title); + } + if (message) { + lcdDrawText(4, 5*FH, message); + } + lcdDrawRect(4, 6*FH+4, LCD_W-8, 7); + if (num > 0 && den > 0) { + int width = ((LCD_W-12)*num)/den; + lcdDrawSolidHorizontalLine(6, 6*FH+6, width, FORCE); + lcdDrawSolidHorizontalLine(6, 6*FH+7, width, FORCE); + lcdDrawSolidHorizontalLine(6, 6*FH+8, width, FORCE); + } + lcdRefresh(); +} diff --git a/radio/src/gui/common/stdlcd/popups.h b/radio/src/gui/common/stdlcd/popups.h new file mode 100644 index 000000000..17806561c --- /dev/null +++ b/radio/src/gui/common/stdlcd/popups.h @@ -0,0 +1,56 @@ +/* + * 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 _STDLCD_POPUPS_H_ +#define _STDLCD_POPUPS_H_ + +extern const char * warningText; +extern const char * warningInfoText; +extern uint8_t warningInfoLength; +extern uint8_t warningResult; +extern uint8_t warningType; +extern uint8_t warningInfoFlags; + +extern void (* popupFunc)(event_t event); +extern uint8_t popupMenuOffsetType; + +extern uint16_t popupMenuOffset; +extern const char * popupMenuItems[POPUP_MENU_MAX_LINES]; +extern uint16_t popupMenuItemsCount; +extern void (* popupMenuHandler)(const char * result); +extern const char * popupMenuTitle; +extern uint8_t s_menu_item; + +// Message box +void drawMessageBoxBackground(coord_t top, coord_t height); +void drawMessageBox(const char * title); +void showMessageBox(const char * title); + +// Popup menu +const char * runPopupMenu(event_t event); +void runPopupWarning(event_t event); + +// Full screen with an alert +void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound); + +// Full screen with 2 lines and a progress bar +void drawProgressScreen(const char * title, const char * message, int num, int den); + +#endif // _STDLCD_POPUPS_H_ diff --git a/radio/src/gui/common/stdlcd/radio_power_meter.cpp b/radio/src/gui/common/stdlcd/radio_power_meter.cpp new file mode 100644 index 000000000..fbe5f96ab --- /dev/null +++ b/radio/src/gui/common/stdlcd/radio_power_meter.cpp @@ -0,0 +1,68 @@ +/* + * 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. + */ + +#include +#include "opentx.h" + +void menuRadioPowerMeter(event_t event) +{ + SIMPLE_SUBMENU("POWER METER", 1); + + if (menuEvent) { + pausePulses(); + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + /* wait 500ms off */ + watchdogSuspend(500); + RTOS_WAIT_MS(500); + resumePulses(); + } + else if (event == EVT_ENTRY) { + memclear(&reusableBuffer.powerMeter, sizeof(reusableBuffer.powerMeter)); + reusableBuffer.powerMeter.freq = 2400; + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_POWER_METER; + } + + coord_t y = MENU_HEADER_HEIGHT + 1 + FH; + LcdFlags attr = (menuVerticalPosition == 0 ? INVERS : 0); + lcdDrawText(0, y, "Freq."); + lcdDrawNumber(8*FW, y, reusableBuffer.powerMeter.freq, LEFT|attr|(s_editMode > 0 ? BLINK : 0)); + lcdDrawText(lcdNextPos, y, "MHz"); + if (attr) { + CHECK_INCDEC_MODELVAR(event, reusableBuffer.powerMeter.freq, 2300, 2500); + if (checkIncDec_Ret) { + reusableBuffer.powerMeter.power = 0; + reusableBuffer.powerMeter.peak = 0; + } + } + + y += FH + 1; + lcdDrawText(0, y, "Power"); + if (reusableBuffer.powerMeter.power) { + lcdDrawNumber(8 * FW, y, reusableBuffer.powerMeter.power, LEFT | PREC2); + lcdDrawText(lcdNextPos, y, "dBm"); + } + + y += FH + 1; + lcdDrawText(0, y, "Peak"); + if (reusableBuffer.powerMeter.peak) { + lcdDrawNumber(8 * FW, y, reusableBuffer.powerMeter.peak, LEFT | PREC2); + lcdDrawText(lcdNextPos, y, "dBm"); + } +} diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index b89cd74f4..ef652d316 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "io/frsky_device_firmware_update.h" #define REFRESH_FILES() do { reusableBuffer.sdmanager.offset = 65535; menuVerticalPosition = 0; } while(0) #define NODE_TYPE(fname) fname[SD_SCREEN_FILE_LENGTH+1] @@ -81,7 +82,7 @@ void onSdManagerMenu(const char * result) pushMenu(menuRadioSdManagerInfo); } else if (result == STR_SD_FORMAT) { - POPUP_CONFIRMATION(STR_CONFIRM_FORMAT); + POPUP_CONFIRMATION(STR_CONFIRM_FORMAT, nullptr); } else if (result == STR_COPY_FILE) { clipboard.type = CLIPBOARD_TYPE_SD_FILE; @@ -141,16 +142,19 @@ void onSdManagerMenu(const char * result) } else if (result == STR_FLASH_INTERNAL_MODULE) { getSelectionFullPath(lfn); - sportFlashDevice(INTERNAL_MODULE, lfn); + DeviceFirmwareUpdate device(INTERNAL_MODULE); + device.flashFile(lfn); } else if (result == STR_FLASH_EXTERNAL_MODULE) { // needed on X-Lite (as the R9M needs 2S while the external device flashing port only provides 5V) getSelectionFullPath(lfn); - sportFlashDevice(EXTERNAL_MODULE, lfn); + DeviceFirmwareUpdate device(EXTERNAL_MODULE); + device.flashFile(lfn); } else if (result == STR_FLASH_EXTERNAL_DEVICE) { getSelectionFullPath(lfn); - sportFlashDevice(FLASHING_MODULE, lfn); + DeviceFirmwareUpdate device(SPORT_MODULE); + device.flashFile(lfn); } #endif #if defined(LUA) @@ -171,7 +175,7 @@ void menuRadioSdManager(event_t _event) Card_state = SD_ST_DATA; #endif audioQueue.stopSD(); - if(sdCardFormat()) { + if (sdCardFormat()) { f_chdir("/"); REFRESH_FILES(); } @@ -197,9 +201,9 @@ void menuRadioSdManager(event_t _event) menuVerticalOffset = reusableBuffer.sdmanager.offset; break; -#if defined(PCBX9) || defined(PCBX7) // TODO NO_MENU_KEY +#if defined(PCBX9) || defined(PCBX7) || defined(PCBX3) // TODO NO_MENU_KEY case EVT_KEY_LONG(KEY_MENU): - if (!READ_ONLY() && s_editMode == 0) { + if (SD_CARD_PRESENT() && !READ_ONLY() && s_editMode == 0) { killEvents(_event); POPUP_MENU_ADD_ITEM(STR_SD_INFO); POPUP_MENU_ADD_ITEM(STR_SD_FORMAT); @@ -234,7 +238,7 @@ void menuRadioSdManager(event_t _event) break; case EVT_KEY_LONG(KEY_ENTER): -#if !defined(PCBX9) && !defined(PCBX7) // TODO NO_HEADER_LINE +#if !defined(PCBX9) && !defined(PCBX7) && !defined(PCBX3)// TODO NO_HEADER_LINE if (menuVerticalPosition < HEADER_LINE) { killEvents(_event); POPUP_MENU_ADD_ITEM(STR_SD_INFO); @@ -243,7 +247,7 @@ void menuRadioSdManager(event_t _event) break; } #endif - if (s_editMode <= 0) { + if (SD_CARD_PRESENT() && s_editMode <= 0) { killEvents(_event); int index = menuVerticalPosition - HEADER_LINE - menuVerticalOffset; char * line = reusableBuffer.sdmanager.lines[index]; @@ -300,132 +304,137 @@ void menuRadioSdManager(event_t _event) break; } - if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { - FILINFO fno; - DIR dir; + if (SD_CARD_PRESENT()) { + if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { + FILINFO fno; + DIR dir; - if (menuVerticalOffset == 0) { - reusableBuffer.sdmanager.offset = 0; - memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); - } - else if (menuVerticalOffset == reusableBuffer.sdmanager.count-NUM_BODY_LINES) { - reusableBuffer.sdmanager.offset = menuVerticalOffset; - memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); - } - else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { - memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], (NUM_BODY_LINES-1)*sizeof(reusableBuffer.sdmanager.lines[0])); - memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0xff, SD_SCREEN_FILE_LENGTH); - NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = 1; - } - else { - memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], (NUM_BODY_LINES-1)*sizeof(reusableBuffer.sdmanager.lines[0])); - memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); - } + if (menuVerticalOffset == 0) { + reusableBuffer.sdmanager.offset = 0; + memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); + } + else if (menuVerticalOffset == reusableBuffer.sdmanager.count-NUM_BODY_LINES) { + reusableBuffer.sdmanager.offset = menuVerticalOffset; + memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); + } + else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { + memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], (NUM_BODY_LINES-1)*sizeof(reusableBuffer.sdmanager.lines[0])); + memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0xff, SD_SCREEN_FILE_LENGTH); + NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = 1; + } + else { + memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], (NUM_BODY_LINES-1)*sizeof(reusableBuffer.sdmanager.lines[0])); + memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); + } - reusableBuffer.sdmanager.count = 0; + reusableBuffer.sdmanager.count = 0; - FRESULT res = f_opendir(&dir, "."); // Open the directory - if (res == FR_OK) { - bool firstTime = true; - for (;;) { - res = sdReadDir(&dir, &fno, firstTime); - if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ - if (strlen(fno.fname) > SD_SCREEN_FILE_LENGTH) continue; - if (fno.fattrib & AM_HID) continue; /* Ignore Windows hidden files */ - if (fno.fname[0] == '.' && fno.fname[1] != '.') continue; /* Ignore UNIX hidden files, but not .. */ + FRESULT res = f_opendir(&dir, "."); // Open the directory + if (res == FR_OK) { + bool firstTime = true; + for (;;) { + res = sdReadDir(&dir, &fno, firstTime); + if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ + if (strlen(fno.fname) > SD_SCREEN_FILE_LENGTH) continue; + if (fno.fattrib & AM_HID) continue; /* Ignore Windows hidden files */ + if (fno.fname[0] == '.' && fno.fname[1] != '.') continue; /* Ignore UNIX hidden files, but not .. */ - reusableBuffer.sdmanager.count++; + reusableBuffer.sdmanager.count++; - bool isfile = !(fno.fattrib & AM_DIR); + bool isfile = !(fno.fattrib & AM_DIR); - if (menuVerticalOffset == 0) { - for (uint8_t i=0; i=0; i--) { + char * line = reusableBuffer.sdmanager.lines[i]; + if (line[0] == '\0' || isFilenameGreater(isfile, fno.fname, line)) { + if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); + memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); + strcpy(line, fno.fname); + NODE_TYPE(line) = isfile; + break; + } + } + } + else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { + if (isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) { + memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0])); + strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fno.fname); + NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile; + } + } + else { + if (isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[0])) { + memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); + strcpy(reusableBuffer.sdmanager.lines[0], fno.fname); + NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile; } } } - else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { - for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) { - char * line = reusableBuffer.sdmanager.lines[i]; - if (line[0] == '\0' || isFilenameGreater(isfile, fno.fname, line)) { - if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); - memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); - strcpy(line, fno.fname); - NODE_TYPE(line) = isfile; - break; - } - } + f_closedir(&dir); + } + } + + reusableBuffer.sdmanager.offset = menuVerticalOffset; + int index = menuVerticalPosition - HEADER_LINE - menuVerticalOffset; + + for (uint8_t i=0; i reusableBuffer.sdmanager.offset) { - if (isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) { - memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0])); - strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fno.fname); - NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile; + if (s_editMode == EDIT_MODIFY_STRING && attr) { + uint8_t extlen, efflen; + const char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, 0, 0, NULL, &extlen); + editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen, _event, attr, 0); + efflen = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH - extlen); + if (s_editMode == 0) { + if (ext) { + strAppend(&reusableBuffer.sdmanager.lines[i][efflen], ext); + } + else { + reusableBuffer.sdmanager.lines[i][efflen] = 0; + } + f_rename(reusableBuffer.sdmanager.originalName, reusableBuffer.sdmanager.lines[i]); + REFRESH_FILES(); } } else { - if (isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[0])) { - memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); - strcpy(reusableBuffer.sdmanager.lines[0], fno.fname); - NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile; - } + lcdDrawText(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr); + } + if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[i])) { + lcdDrawChar(lcdNextPos, y, ']', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } } - f_closedir(&dir); } - } - - reusableBuffer.sdmanager.offset = menuVerticalOffset; - int index = menuVerticalPosition - HEADER_LINE - menuVerticalOffset; - - for (uint8_t i=0; i 1 - const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); - if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { - if (lastPos != menuVerticalPosition) { - if (!lcdLoadBitmap(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { - memcpy(modelBitmap, logo_taranis, MODEL_BITMAP_SIZE); + const char * ext = getFileExtension(reusableBuffer.sdmanager.lines[index]); + if (ext && isExtensionMatching(ext, BITMAPS_EXT)) { + if (lastPos != menuVerticalPosition) { + if (!lcdLoadBitmap(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { + memcpy(modelBitmap, logo_taranis, MODEL_BITMAP_SIZE); + } } + lcdDrawBitmap(22*FW+2, 2*FH+FH/2, modelBitmap); } - lcdDrawBitmap(22*FW+2, 2*FH+FH/2, modelBitmap); - } #endif + } + else { + lcdDrawText(6*FW+3, 4*FH, STR_NO_SDCARD); + } } diff --git a/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp new file mode 100644 index 000000000..b8ab58cbf --- /dev/null +++ b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#include "opentx.h" + +void menuRadioSpectrumAnalyser(event_t event) +{ + SIMPLE_SUBMENU("SPECTRUM ANALYSER", 1); + + if (menuEvent) { + pausePulses(); + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + /* wait 500ms off */ + watchdogSuspend(500); + RTOS_WAIT_MS(500); + resumePulses(); + } + else if (event == EVT_ENTRY) { + memclear(reusableBuffer.spectrumAnalyser.bars, sizeof(reusableBuffer.spectrumAnalyser.bars)); + moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_SPECTRUM_ANALYSER; + } + + uint8_t peak_y = 1; + uint8_t peak_x = 0; + for (uint8_t i=0; i(reusableBuffer.spectrumAnalyser.bars[i] >> 1, 128); + if (h > peak_y) { + peak_x = i; + peak_y = h; + } + lcdDrawSolidVerticalLine(i, LCD_H - h, h); + } + + lcdDrawText(1, 10, "F:", 0); + lcdDrawNumber(lcdLastRightPos + 2, 10, reusableBuffer.spectrumAnalyser.freq / 10000000, PREC2); + lcdDrawText(lcdLastRightPos + 2, 10, "GHz", 0); + + lcdDrawText(lcdLastRightPos + 5, 10, "S:", 0); + lcdDrawNumber(lcdLastRightPos + 2, 10, reusableBuffer.spectrumAnalyser.span/1000000, 0); + lcdDrawText(lcdLastRightPos + 2, 10, "MHz", 0); + + 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 / 128)) / 1000000, TINSIZE); + lcdDrawText(lcdLastRightPos, y, "M", TINSIZE); +} diff --git a/radio/src/gui/common/stdlcd/radio_tools.cpp b/radio/src/gui/common/stdlcd/radio_tools.cpp new file mode 100644 index 000000000..25efb65ed --- /dev/null +++ b/radio/src/gui/common/stdlcd/radio_tools.cpp @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#include "opentx.h" + +void addRadioTool(uint8_t index, const char * label, void (* tool)(event_t event), event_t event) +{ + int8_t sub = menuVerticalPosition - HEADER_LINE; + LcdFlags attr = (sub == index ? INVERS : 0); + coord_t y = MENU_HEADER_HEIGHT + 1 + index * FH; + lcdDrawNumber(3, y, index + 1, LEADING0|LEFT, 2); + lcdDrawText(3*FW, y, label, (sub == index ? INVERS : 0)); + if (attr && s_editMode > 0) { + s_editMode = 0; + pushMenu(tool); + } +} + +void menuRadioTools(event_t event) +{ + SIMPLE_MENU("TOOLS", menuTabGeneral, MENU_RADIO_TOOLS, HEADER_LINE + 2); + +#if defined(PXX2) + addRadioTool(0, "Spectrum Analyser", menuRadioSpectrumAnalyser, event); + addRadioTool(1, "Power Meter", menuRadioPowerMeter, event); +#endif +} \ No newline at end of file diff --git a/radio/src/gui/common/stdlcd/widgets.cpp b/radio/src/gui/common/stdlcd/widgets.cpp index c1b60ec32..266ec6446 100644 --- a/radio/src/gui/common/stdlcd/widgets.cpp +++ b/radio/src/gui/common/stdlcd/widgets.cpp @@ -69,7 +69,7 @@ void editName(coord_t x, coord_t y, char * name, uint8_t size, event_t event, ui else mode = FIXEDWIDTH; } - + lcdDrawSizedText(x, y, name, size, attr | mode); coord_t backupNextPos = lcdNextPos; @@ -156,11 +156,11 @@ void editName(coord_t x, coord_t y, char * name, uint8_t size, event_t event, ui if (c != v) { name[cur] = v; - storageDirty(menuVerticalPositions[0] == 0 ? EE_MODEL : EE_GENERAL); + storageDirty(isModelMenuDisplayed() ? EE_MODEL : EE_GENERAL); } if (attr == ZCHAR) { - lcdDrawChar(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH); + lcdDrawChar(x+editNameCursorPos*FW, y, zchar2char(v), ERASEBG|INVERS|FIXEDWIDTH); } else { lcdDrawChar(x+editNameCursorPos*FW, y, v, ERASEBG|INVERS|FIXEDWIDTH); diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index c48ee4463..8a1b5dccd 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -54,7 +54,11 @@ bool isSwitchAvailableInCustomFunctions(int swtch); bool isSwitchAvailableInMixes(int swtch); bool isSwitchAvailableInTimers(int swtch); bool isR9MModeAvailable(int mode); -bool isModuleAvailable(int module); +bool isR9ModuleRunning(int module); +bool isR9MMFlex(int module); +bool isPXX2ChannelsCountAllowed(int channels); +bool isExternalModuleAvailable(int module); +bool isInternalModuleAvailable(int module); bool isRfProtocolAvailable(int protocol); bool isTelemetryProtocolAvailable(int protocol); bool isTrainerModeAvailable(int mode); @@ -112,6 +116,7 @@ void runFatalErrorScreen(const char * message); void lcdDrawMMM(coord_t x, coord_t y, LcdFlags flags=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) != MM_RF_PROTO_DSM2)) ? (uint8_t)0 : (uint8_t)1) @@ -148,23 +153,26 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); #define MULTIMODULE_OPTIONS_ROW HIDDEN_ROW #endif - #define MAX_RX_NUM(x) (isModuleDSM2(x) ? 20 : isModuleMultimodule(x) ? MULTI_MAX_RX_NUM(x) : 63) #define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8) #define IS_R9M_OR_XJTD16(x) ((isModuleXJT(x) && g_model.moduleData[x].rfProtocol== RF_PROTO_X16) || isModuleR9M(x)) -#define FAILSAFE_ROWS(x) ((isModuleXJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || isModuleR9M(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW +#define FAILSAFE_ROWS(x) ((isModuleXJTVariant(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || isModuleR9M(x) || isModuleR9M2(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW -#define EXTERNAL_MODULE_OPTION_ROW (isModuleR9M(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#if defined(PCBXLITE) + #define EXTERNAL_MODULE_OPTION_ROW (isModuleR9M(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#else + #define EXTERNAL_MODULE_OPTION_ROW (isR9ModuleRunning(EXTERNAL_MODULE) ? HIDDEN_ROW : isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) +#endif #if defined(PCBXLITE) && !defined(MODULE_R9M_FULLSIZE) -#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (isModuleR9M_FCC_VARIANT(EXTERNAL_MODULE) ? TITLE_ROW : (uint8_t) 0) : HIDDEN_ROW + #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (isModuleR9M_FCC_VARIANT(EXTERNAL_MODULE) ? TITLE_ROW : (uint8_t) 0) : HIDDEN_ROW +#elif defined(PCBXLITE) + #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW #else -#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW + #define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isR9ModuleRunning(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW #endif void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); - - #endif // _GUI_COMMON_H_ diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index 5d6b1fe0a..49281630c 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -486,6 +486,15 @@ bool isSourceAvailableInResetSpecialFunction(int index) } } +bool isR9ModuleRunning(int module) +{ +#if defined(SIMU) + return g_model.moduleData[module].type == MODULE_TYPE_R9M && TELEMETRY_STREAMING(); // Simu uses telemetry simu to activate/desactivate R9 +#else + return g_model.moduleData[module].type == MODULE_TYPE_R9M && R9ModuleStreaming; +#endif +} +#if defined(PCBXLITE) bool isR9MModeAvailable(int mode) { #if defined(MODULE_R9M_FLEX_FW) @@ -495,8 +504,59 @@ bool isR9MModeAvailable(int mode) #endif } -bool isModuleAvailable(int module) +#else +bool isR9MModeAvailable(int mode) { + return mode <= MODULE_SUBTYPE_R9M_EUPLUS; +} +#endif +bool isR9MMFlex(int module) +{ + return g_model.moduleData[module].r9m.region == MODULE_R9M_REGION_FLEX; +} + +bool isPXX2ChannelsCountAllowed(int channels) +{ + return (channels % 8 == 0); +} + +#if defined(HARDWARE_INTERNAL_MODULE) +bool isInternalModuleAvailable(int module) +{ + if (module == MODULE_TYPE_NONE) + return true; + +#if defined(PXX1) + if (module == MODULE_TYPE_XJT) + return IS_PXX1_INTERNAL_ENABLED() && !isModulePXX(EXTERNAL_MODULE); +#endif + +#if defined(PXX2) + if (module == MODULE_TYPE_XJT2) + return IS_PXX2_INTERNAL_ENABLED(); +#endif + + return false; +} +#endif + +bool isExternalModuleAvailable(int module) +{ +#if !defined(PCBXLITE) + if (module == MODULE_TYPE_R9M_LITE || module == MODULE_TYPE_R9M_LITE2 || module == MODULE_TYPE_R9M_LITE_PRO2) { + return false; + } +#endif +#if !defined(PXX1) + if (module == MODULE_TYPE_XJT || module == MODULE_TYPE_R9M || module == MODULE_TYPE_R9M_LITE) { + return false; + } +#endif +#if !defined(PXX2) + if (module == MODULE_TYPE_XJT2 || module == MODULE_TYPE_R9M2 || module == MODULE_TYPE_R9M_LITE2 || module == MODULE_TYPE_R9M_LITE_PRO2) { + return false; + } +#endif #if defined(CROSSFIRE) if (module == MODULE_TYPE_CROSSFIRE && g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) { return false; @@ -516,6 +576,15 @@ bool isModuleAvailable(int module) return false; } #endif +#if defined(HARDWARE_INTERNAL_MODULE) + if (module == MODULE_TYPE_R9M && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT) { + return false; + } + if (module == MODULE_TYPE_XJT && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT) { + return false; + } +#endif + return true; } @@ -531,29 +600,38 @@ bool isRfProtocolAvailable(int protocol) return false; } #endif +#if defined(PCBTARANIS) || defined(PCBHORUS) + if (protocol != RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M) { + return false; + } + if (protocol != RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M2) { + return false; + } +#endif + return true; } bool isTelemetryProtocolAvailable(int protocol) { #if defined(PCBTARANIS) - if (protocol == PROTOCOL_FRSKY_D_SECONDARY && g_eeGeneral.serial2Mode != UART_MODE_TELEMETRY) { + if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY && g_eeGeneral.serial2Mode != UART_MODE_TELEMETRY) { return false; } #endif - if (protocol== PROTOCOL_PULSES_CROSSFIRE) { + if (protocol== PROTOCOL_TELEMETRY_CROSSFIRE) { return false; } #if !defined(MULTIMODULE) - if (protocol == PROTOCOL_SPEKTRUM || protocol == PROTOCOL_FLYSKY_IBUS || protocol == PROTOCOL_MULTIMODULE) { + if (protocol == PROTOCOL_TELEMETRY_SPEKTRUM || protocol == PROTOCOL_TELEMETRY_FLYSKY_IBUS || protocol == PROTOCOL_TELEMETRY_MULTIMODULE) { return false; } #endif #if defined(PCBHORUS) - if (protocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { return false; } #endif @@ -588,7 +666,7 @@ bool isTrainerModeAvailable(int mode) else return true; } -#elif defined(PCBX7) +#elif defined(PCBX7) || defined(PCBXLITES) || defined(PCBX3) bool isTrainerModeAvailable(int mode) { if (IS_EXTERNAL_MODULE_ENABLED() && (mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || mode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE)) @@ -602,13 +680,23 @@ bool isTrainerModeAvailable(int mode) else return true; } +#elif defined(PCBXLITES) +bool isTrainerModeAvailable(int mode) +{ + if (mode == TRAINER_MODE_MASTER_TRAINER_JACK || mode == TRAINER_MODE_SLAVE) + return true; + else if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH)) + return true; + else + return false; +} #elif defined(PCBXLITE) bool isTrainerModeAvailable(int mode) { if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH)) - return true; + return true; else - return false; + return false; } #endif diff --git a/radio/src/gui/navigation/navigation_9x.cpp b/radio/src/gui/navigation/navigation_9x.cpp index 63569e4b9..f4336e194 100644 --- a/radio/src/gui/navigation/navigation_9x.cpp +++ b/radio/src/gui/navigation/navigation_9x.cpp @@ -27,14 +27,6 @@ uint8_t menuCalibrationState; vertpos_t menuVerticalPosition; horzpos_t menuHorizontalPosition; -#if defined(NAVIGATION_POT1) -int16_t p1valdiff; -#endif - -#if defined(NAVIGATION_POT2) -int8_t p2valdiff; -#endif - int8_t checkIncDec_Ret; #define DBLKEYS_PRESSED_RGT_LFT(in) ((in & (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT)) == (KEYS_GPIO_PIN_RIGHT + KEYS_GPIO_PIN_LEFT)) @@ -126,12 +118,6 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla newval = !val; } -#if defined(NAVIGATION_POT1) - // change values based on P1 - newval -= p1valdiff; - p1valdiff = 0; -#endif - #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { newval = checkIncDecMovedSwitch(newval); @@ -172,7 +158,6 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla return newval; } -#define SCROLL_TH 64 #define SCROLL_POT1_TH 32 #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) @@ -192,36 +177,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t uint8_t maxcol = MAXCOL(l_posVert); -#if defined(NAVIGATION_POT1) - // check pot 1 - if changed -> scroll values - static int16_t p1val; - static int16_t p1valprev; - p1valdiff = (p1val-calibratedAnalogs[CALIBRATED_POT1]) / SCROLL_POT1_TH; - if (p1valdiff) { - p1valdiff = (p1valprev-calibratedAnalogs[CALIBRATED_POT1]) / 2; - p1val = calibratedAnalogs[CALIBRATED_POT1]; - } - p1valprev = calibratedAnalogs[CALIBRATED_POT1]; -#endif - -#if defined(NAVIGATION_POT2) - // check pot 2 - if changed -> scroll menu - static int16_t p2valprev; - p2valdiff = (p2valprev-calibratedAnalogs[CALIBRATED_POT2]) / SCROLL_TH; - if (p2valdiff) p2valprev = calibratedAnalogs[CALIBRATED_POT2]; -#endif - -#if defined(NAVIGATION_POT3) - // check pot 3 if changed -> cursor down/up - static int16_t p3valprev; - int8_t scrollUD = (p3valprev-calibratedAnalogs[CALIBRATED_POT3]) / SCROLL_TH; - if (scrollUD) p3valprev = calibratedAnalogs[CALIBRATED_POT3]; -#else - #define scrollUD 0 -#endif - - if (p2valdiff || scrollUD || p1valdiff) backlightOn(); // on keypress turn the light on - if (menuTab) { uint8_t attr = 0; @@ -230,10 +185,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t int8_t cc = curr; - if (p2valdiff) { - cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1)); - } - switch (event) { #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: @@ -289,19 +240,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t } - DISPLAY_PROGRESS_BAR(menuTab ? lcdLastRightPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); - - if (s_editMode<=0) { - if (scrollUD) { - l_posVert = limit((int8_t)0, (int8_t)(l_posVert - scrollUD), (int8_t)maxrow); - l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); - } - - if (p2valdiff && l_posVert>0) { - l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol); - } - } - switch (event) { case EVT_ENTRY: diff --git a/radio/src/gui/navigation/navigation_x7.cpp b/radio/src/gui/navigation/navigation_x7.cpp index d084b6a60..f5553267b 100644 --- a/radio/src/gui/navigation/navigation_x7.cpp +++ b/radio/src/gui/navigation/navigation_x7.cpp @@ -230,7 +230,6 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla return newval; } -#define SCROLL_TH 64 #define SCROLL_POT1_TH 32 #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) @@ -285,8 +284,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t drawScreenIndex(curr, menuTabSize, 0); } - DISPLAY_PROGRESS_BAR(menuTab ? lcdLastRightPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); - switch (event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); diff --git a/radio/src/gui/navigation/navigation_x9d.cpp b/radio/src/gui/navigation/navigation_x9d.cpp index a56ca656a..1cfb7d438 100644 --- a/radio/src/gui/navigation/navigation_x9d.cpp +++ b/radio/src/gui/navigation/navigation_x9d.cpp @@ -393,8 +393,6 @@ void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc lcdDrawFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, SOLID, FILL_WHITE|GREY_DEFAULT); } - DISPLAY_PROGRESS_BAR(menuTab ? lcdLastRightPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); - switch (event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); diff --git a/radio/src/gui/navigation/navigation_xlite.cpp b/radio/src/gui/navigation/navigation_xlite.cpp index c0210caef..327c3d209 100644 --- a/radio/src/gui/navigation/navigation_xlite.cpp +++ b/radio/src/gui/navigation/navigation_xlite.cpp @@ -172,7 +172,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla } } - if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { + if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER))) { s_editMode = 0; newval = !val; } @@ -185,7 +185,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { - if (s_editMode>0) { + if (s_editMode > 0) { int8_t source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; @@ -203,7 +203,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla #endif if (newval != val) { - if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) { + if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100)) { pauseEvents(event); // delay before auto-repeat continues } AUDIO_KEY_PRESS(); @@ -292,7 +292,6 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla return newval; } -#define SCROLL_TH 64 #define SCROLL_POT1_TH 32 #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) @@ -322,25 +321,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t int8_t cc = curr; switch (event) { -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ROTARY_BREAK: - if (s_editMode < 0 && maxrow > 0) { - s_editMode = 0; - // TODO ? l_posVert = (horTab && horTab[1]==0xff) ? 2 : 1; - l_posHorz = 0; - } - else { - s_editMode = -1; - } - event = 0; - break; -#endif - -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ROTARY_LEFT: - if (s_editMode >= 0) - break; -#endif case EVT_KEY_FIRST(KEY_LEFT): if (curr > 0) cc = curr - 1; @@ -348,11 +328,6 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t cc = menuTabSize-1; break; -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ROTARY_RIGHT: - if (s_editMode >= 0) - break; -#endif case EVT_KEY_FIRST(KEY_RIGHT): if (curr < (menuTabSize-1)) cc = curr + 1; @@ -364,65 +339,29 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t if (cc != curr) { chainMenu(menuTab[cc]); } - -#if defined(ROTARY_ENCODER_NAVIGATION) - if (IS_ROTARY_ENCODER_NAVIGATION_ENABLE() && s_editMode < 0) - attr = INVERS|BLINK; -#endif } menuCalibrationState = 0; drawScreenIndex(curr, menuTabSize, attr); - } - DISPLAY_PROGRESS_BAR(menuTab ? lcdLastRightPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); - switch (event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); l_posVert = 0; l_posHorz = POS_HORZ_INIT(l_posVert); -#if defined(ROTARY_ENCODER_NAVIGATION) - if (menuTab) { - s_editMode = EDIT_MODE_INIT; - break; - } - // no break -#else s_editMode = EDIT_MODE_INIT; break; -#endif - -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ENTRY_UP: - s_editMode = 0; - break; - - case EVT_ROTARY_BREAK: - if (s_editMode > 1) break; -#endif case EVT_KEY_FIRST(KEY_ENTER): - if (!menuTab || l_posVert>0) { + if (!menuTab || l_posVert > 0) { if (READ_ONLY_UNLOCKED()) { - s_editMode = (s_editMode<=0); + s_editMode = (s_editMode <= 0); } } break; -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ROTARY_LONG: - if (s_editMode > 1) break; - killEvents(event); - if (l_posVert != 0) { - l_posVert = 0; - s_editMode = EDIT_MODE_INIT; - break; - } - // no break -#endif case EVT_KEY_LONG(KEY_EXIT): s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same popMenu(); @@ -430,17 +369,12 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t case EVT_KEY_BREAK(KEY_EXIT): AUDIO_KEY_PRESS(); -#if defined(ROTARY_ENCODER_NAVIGATION) - if (s_editMode == 0) - s_editMode = EDIT_MODE_INIT; - else -#endif - if (s_editMode>0) { + if (s_editMode > 0) { s_editMode = 0; break; } - if (l_posVert==0 || !menuTab) { + if (l_posVert == 0 || !menuTab) { popMenu(); // beeps itself } else { @@ -450,43 +384,23 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t break; case EVT_KEY_REPT(KEY_RIGHT): //inc - if (l_posHorz==maxcol) break; + if (l_posHorz == maxcol) break; // no break case EVT_KEY_FIRST(KEY_RIGHT)://inc - if (!horTab || s_editMode>0) break; - -#if defined(ROTARY_ENCODER_NAVIGATION) - CASE_EVT_ROTARY_RIGHT - if (s_editMode != 0) break; - if (l_posHorz < maxcol) { - l_posHorz++; - break; - } - else { - l_posHorz = 0; - if (!IS_ROTARY_RIGHT(event)) - break; - } -#else + if (!horTab || s_editMode > 0) break; INC(l_posHorz, 0, maxcol); break; -#endif case EVT_KEY_REPT(KEY_DOWN): - if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break; + if (l_posVert == maxrow) break; // no break case EVT_KEY_FIRST(KEY_DOWN): - if (s_editMode>0) break; + if (s_editMode > 0) break; do { INC(l_posVert, 0, maxrow); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); - -#if defined(ROTARY_ENCODER_NAVIGATION) - s_editMode = 0; // if we go down, we must be in this mode -#endif - l_posHorz = min(l_posHorz, MAXCOL(l_posVert)); break; @@ -495,41 +409,18 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t // no break case EVT_KEY_FIRST(KEY_LEFT)://dec - if (!horTab || s_editMode>0) break; - -#if defined(ROTARY_ENCODER_NAVIGATION) - CASE_EVT_ROTARY_LEFT - if (s_editMode != 0) break; - if (l_posHorz > 0) { - l_posHorz--; - break; - } - else if (IS_ROTARY_LEFT(event) && s_editMode == 0) { - l_posHorz = 0xff; - } - else { - l_posHorz = maxcol; - break; - } -#else + if (!horTab || s_editMode > 0) break; DEC(l_posHorz, 0, maxcol); break; -#endif case EVT_KEY_REPT(KEY_UP): - if (!IS_ROTARY_LEFT(event) && l_posVert==0) break; + if (l_posVert == 0) break; // no break case EVT_KEY_FIRST(KEY_UP): - if (s_editMode>0) break; - + if (s_editMode > 0) break; do { DEC(l_posVert, 0, maxrow); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); - -#if defined(ROTARY_ENCODER_NAVIGATION) - s_editMode = 0; // if we go up, we must be in this mode -#endif - l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); break; } diff --git a/radio/src/io/bootloader_flash.cpp b/radio/src/io/bootloader_flash.cpp index 612fe4e88..7259b2f6a 100644 --- a/radio/src/io/bootloader_flash.cpp +++ b/radio/src/io/bootloader_flash.cpp @@ -60,7 +60,7 @@ void bootloaderFlash(const char * filename) for (int j=0; j<1024; j+=FLASH_PAGESIZE) { flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS+i+j), (uint32_t *)(buffer+j)); } - drawProgressBar(STR_WRITING, i, BOOTLOADER_SIZE); + drawProgressScreen("Bootloader", STR_WRITING, i, BOOTLOADER_SIZE); #if defined(SIMU) // add an artificial delay and check for simu quit if (SIMU_SLEEP_OR_EXIT_MS(30)) diff --git a/radio/src/io/frsky_device_firmware_update.cpp b/radio/src/io/frsky_device_firmware_update.cpp new file mode 100644 index 000000000..99ab6e30c --- /dev/null +++ b/radio/src/io/frsky_device_firmware_update.cpp @@ -0,0 +1,365 @@ +/* + * 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. + */ + +#include "opentx.h" +#include "frsky_device_firmware_update.h" + +#define PRIM_REQ_POWERUP 0 +#define PRIM_REQ_VERSION 1 +#define PRIM_CMD_DOWNLOAD 3 +#define PRIM_DATA_WORD 4 +#define PRIM_DATA_EOF 5 + +#define PRIM_ACK_POWERUP 0x80 +#define PRIM_ACK_VERSION 0x81 +#define PRIM_REQ_DATA_ADDR 0x82 +#define PRIM_END_DOWNLOAD 0x83 +#define PRIM_DATA_CRC_ERR 0x84 + +void DeviceFirmwareUpdate::processFrame(const uint8_t * frame) +{ + if (frame[0] == 0x5E && frame[1] == 0x50) { + switch (frame[2]) { + case PRIM_ACK_POWERUP : + if (state == SPORT_POWERUP_REQ) { + state = SPORT_POWERUP_ACK; + } + break; + + case PRIM_ACK_VERSION: + if (state == SPORT_VERSION_REQ) { + state = SPORT_VERSION_ACK; + // here we could display the version + } + break; + + case PRIM_REQ_DATA_ADDR: + if (state == SPORT_DATA_TRANSFER) { + address = *((uint32_t *)(&frame[3])); + state = SPORT_DATA_REQ; + } + break; + + case PRIM_END_DOWNLOAD : + state = SPORT_COMPLETE ; + break; + + case PRIM_DATA_CRC_ERR : + state = SPORT_FAIL ; + break; + } + } +} + +void DeviceFirmwareUpdate::startup() +{ + switch(module) { +#if defined(INTMODULE_USART) + case INTERNAL_MODULE: + intmoduleSerialStart(57600, true); + break; +#endif + + default: + telemetryInit(PROTOCOL_TELEMETRY_FRSKY_SPORT); + break; + } + + if (module == INTERNAL_MODULE) + INTERNAL_MODULE_ON(); + else if (module == EXTERNAL_MODULE) + EXTERNAL_MODULE_ON(); + else + SPORT_UPDATE_POWER_ON(); +} + +const uint8_t * DeviceFirmwareUpdate::readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout) +{ + uint8_t len = 0; + bool bytestuff = false; + while (len < 10) { + uint32_t elapsed = 0; + uint8_t byte; + while (!fifo.pop(byte)) { + RTOS_WAIT_MS(1); + if (elapsed++ >= timeout) { + return nullptr; + } + } + if (byte == 0x7D) { + bytestuff = true; + continue; + } + if (bytestuff) { + frame[len] = 0x20 ^ byte; + bytestuff = false; + } + else { + frame[len] = byte; + } + if (len > 0 || byte == 0x7E) { + ++len; + } + } + return &frame[1]; +} + +const uint8_t * DeviceFirmwareUpdate::readHalfDuplexFrame(uint32_t timeout) +{ + for (int i=timeout; i>=0; i--) { + uint8_t byte ; + while (telemetryGetByte(&byte)) { + if (pushFrskyTelemetryData(byte)) { + return telemetryRxBuffer; + } + } + RTOS_WAIT_MS(1); + } + return nullptr; +} + +const uint8_t * DeviceFirmwareUpdate::readFrame(uint32_t timeout) +{ + switch(module) { +#if defined(INTMODULE_USART) + case INTERNAL_MODULE: + return readFullDuplexFrame(intmoduleFifo, timeout); +#endif + + default: + return readHalfDuplexFrame(timeout); + } +} + +bool DeviceFirmwareUpdate::waitState(State newState, uint32_t timeout) +{ +#if defined(SIMU) + UNUSED(state); + UNUSED(timeout); + static uint8_t pass = 0; + if (++pass == 10) { + pass = 0; + RTOS_WAIT_MS(1); + } + return true; +#else + watchdogSuspend(timeout / 10); + + const uint8_t * frame = readFrame(timeout); + if (!frame) { + return false; + } + + processFrame(frame); + return state == newState; +#endif +} + +void DeviceFirmwareUpdate::startFrame(uint8_t command) +{ + frame[0] = 0x50; + frame[1] = command; + memset(&frame[2], 0, 6); +} + +// TODO merge this function +void DeviceFirmwareUpdate::sendFrame() +{ + uint8_t * ptr = outputTelemetryBuffer.data; + *ptr++ = 0x7E; + *ptr++ = 0xFF; + frame[7] = crc16(frame, 7); + for (int i=0; i<8; i++) { + if (frame[i] == 0x7E || frame[i] == 0x7D) { + *ptr++ = 0x7D; + *ptr++ = 0x20 ^ frame[i]; + } + else { + *ptr++ = frame[i]; + } + } + + switch(module) { +#if defined(INTMODULE_USART) + case INTERNAL_MODULE: + return intmoduleSendBuffer(outputTelemetryBuffer.data, ptr - outputTelemetryBuffer.data); +#endif + + default: + return sportSendBuffer(outputTelemetryBuffer.data, ptr - outputTelemetryBuffer.data); + } +} + +const char * DeviceFirmwareUpdate::sendPowerOn() +{ + state = SPORT_POWERUP_REQ; + waitState(SPORT_IDLE, 50); // Wait 50ms and clear the fifo + for (int i=0; i<10; i++) { + // max 10 attempts + startFrame(PRIM_REQ_POWERUP); + sendFrame(); + if (waitState(SPORT_POWERUP_ACK, 100)) + return nullptr; + } + + if (telemetryProtocol != PROTOCOL_TELEMETRY_FRSKY_SPORT) { + return TR("Not responding", "Not S.Port 1"); + } + + if (!IS_FRSKY_SPORT_PROTOCOL()) { + return TR("Not responding", "Not S.Port 2"); + } +#if defined(PCBX7) + if (IS_PCBREV_40()) { + return TR("Bottom pin no resp", "Bottom pin not responding"); + } + else { + return TR("Device pin no resp", "Device pin not responding"); + } +#else + return TR("Not responding", "Device not responding"); +#endif +} + +const char * DeviceFirmwareUpdate::sendReqVersion() +{ + waitState(SPORT_IDLE, 20); // Clear the fifo + state = SPORT_VERSION_REQ; + for (int i=0; i<10; i++) { + // max 10 attempts + startFrame(PRIM_REQ_VERSION) ; + sendFrame(); + if (waitState(SPORT_VERSION_ACK, 100)) + return nullptr; + } + return "Version request failed"; +} + +const char * DeviceFirmwareUpdate::uploadFile(const char *filename) +{ + FIL file; + uint32_t buffer[1024 / sizeof(uint32_t)]; + UINT count; + + if (f_open(&file, filename, FA_READ) != FR_OK) { + return "Error opening file"; + } + + waitState(SPORT_IDLE, 200); // Clear the fifo + state = SPORT_DATA_TRANSFER; + startFrame(PRIM_CMD_DOWNLOAD); + sendFrame(); + + while (1) { + if (f_read(&file, buffer, 1024, &count) != FR_OK) { + f_close(&file); + return "Error reading file"; + } + + count >>= 2; + + for (uint32_t i=0; i> 2; // 32 bit word offset into buffer + *((uint32_t *)(frame + 2)) = buffer[offset]; + frame[6] = address & 0x000000FF; + state = SPORT_DATA_TRANSFER, + sendFrame(); + if (i == 0) { + drawProgressScreen(getBasename(filename), STR_WRITING, file.fptr, file.obj.objsize); + } + } + + if (count < 256) { + f_close(&file); + return nullptr; + } + } +} + +const char * DeviceFirmwareUpdate::endTransfer() +{ + if (!waitState(SPORT_DATA_REQ, 2000)) + return "Device refused data"; + startFrame(PRIM_DATA_EOF); + sendFrame(); + if (!waitState(SPORT_COMPLETE, 2000)) { + return "Device rejected firmware"; + } + return nullptr; +} + +void DeviceFirmwareUpdate::flashFile(const char * filename) +{ + pausePulses(); + + uint8_t intPwr = IS_INTERNAL_MODULE_ON(); + uint8_t extPwr = IS_EXTERNAL_MODULE_ON(); + + drawProgressScreen(getBasename(filename), "Device reset...", 0, 0); + + INTERNAL_MODULE_OFF(); + EXTERNAL_MODULE_OFF(); + SPORT_UPDATE_POWER_OFF(); + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + startup(); + + const char * result = sendPowerOn(); + if (!result) result = sendReqVersion(); + if (!result) result = uploadFile(filename); + if (!result) result = endTransfer(); + + 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(); + + waitState(SPORT_IDLE, 500); // Clear the fifo + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + if (intPwr) + INTERNAL_MODULE_ON(); + if (extPwr) + EXTERNAL_MODULE_ON(); + + state = SPORT_IDLE; + + resumePulses(); +} diff --git a/radio/src/io/frsky_device_firmware_update.h b/radio/src/io/frsky_device_firmware_update.h new file mode 100644 index 000000000..729120895 --- /dev/null +++ b/radio/src/io/frsky_device_firmware_update.h @@ -0,0 +1,70 @@ +/* + * 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 _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ +#define _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ + +#include "dataconstants.h" +#include "frsky_pxx2.h" + +class DeviceFirmwareUpdate { + enum State { + SPORT_IDLE, + SPORT_POWERUP_REQ, + SPORT_POWERUP_ACK, + SPORT_VERSION_REQ, + SPORT_VERSION_ACK, + SPORT_DATA_TRANSFER, + SPORT_DATA_REQ, + SPORT_COMPLETE, + SPORT_FAIL + }; + + public: + DeviceFirmwareUpdate(ModuleIndex module): + module(module) { + } + + void flashFile(const char * filename); + + protected: + uint8_t state = SPORT_IDLE; + uint32_t address = 0; + ModuleIndex module; + uint8_t frame[12]; + + void startup(); + + void startFrame(uint8_t command); + void sendFrame(); + + const uint8_t * readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout); + const uint8_t * readHalfDuplexFrame(uint32_t timeout); + const uint8_t * readFrame(uint32_t timeout); + bool waitState(State state, uint32_t timeout); + void processFrame(const uint8_t * frame); + + const char * sendPowerOn(); + const char * sendReqVersion(); + const char * uploadFile(const char * filename); + const char * endTransfer(); +}; + +#endif // _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ diff --git a/radio/src/io/frsky_pxx2.h b/radio/src/io/frsky_pxx2.h new file mode 100644 index 000000000..9aec8ab3d --- /dev/null +++ b/radio/src/io/frsky_pxx2.h @@ -0,0 +1,70 @@ +/* + * 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 _IO_PXX2_H_ +#define _IO_PXX2_H_ + +#include "../fifo.h" +#include "../pulses/pxx.h" + +class ModuleFifo : public Fifo { + public: + bool getFrame(uint8_t * frame) + { + while (1) { + if (isEmpty()) { + return false; + } + else if (fifo[ridx] != 0x7E) { + skip(); + } + else { + break; + } + } + + uint32_t next = nextIndex(ridx); + uint8_t len = fifo[next]; + + if (len > 40) { + clear(); + return false; + } + + if (size() < unsigned(len + 4 /* 2 bytes header + 2 bytes CRC */)) { + // frame not fully received + return false; + } + + for (uint32_t i = 0; i <= len; i++) { + frame[i] = fifo[next]; + next = nextIndex(next); + } + + // TODO CRC CHECK + next = nextIndex(next); + ridx = nextIndex(next); + return true; + } + + uint32_t errors; +}; + +#endif diff --git a/radio/src/io/frsky_sport.cpp b/radio/src/io/frsky_sport.cpp index a65de6159..adf249382 100644 --- a/radio/src/io/frsky_sport.cpp +++ b/radio/src/io/frsky_sport.cpp @@ -20,51 +20,22 @@ #include "opentx.h" -#if defined(STM32) -#define PRIM_REQ_POWERUP (0) -#define PRIM_REQ_VERSION (1) -#define PRIM_CMD_DOWNLOAD (3) -#define PRIM_DATA_WORD (4) -#define PRIM_DATA_EOF (5) - -#define PRIM_ACK_POWERUP (0x80) -#define PRIM_ACK_VERSION (0x81) -#define PRIM_REQ_DATA_ADDR (0x82) -#define PRIM_END_DOWNLOAD (0x83) -#define PRIM_DATA_CRC_ERR (0x84) - -enum SportUpdateState { - SPORT_IDLE, - SPORT_POWERUP_REQ, - SPORT_POWERUP_ACK, - SPORT_VERSION_REQ, - SPORT_VERSION_ACK, - SPORT_DATA_TRANSFER, - SPORT_DATA_REQ, - SPORT_COMPLETE, - SPORT_FAIL -}; - -uint8_t sportUpdateState = SPORT_IDLE; -uint32_t sportUpdateAddr = 0; +bool isTelemetryOutputBufferAvailable() +{ + return (outputTelemetryBuffer.size == 0 && outputTelemetryBuffer.trigger == 0x7E); +} void sportOutputPushByte(uint8_t byte) { if (byte == 0x7E || byte == 0x7D) { - telemetryOutputPushByte(0x7D); - telemetryOutputPushByte(0x20 ^ byte); + outputTelemetryBuffer.push(0x7D); + outputTelemetryBuffer.push(0x20 ^ byte); } else { - telemetryOutputPushByte(byte); + outputTelemetryBuffer.push(byte); } } -bool isSportOutputBufferAvailable() -{ - return (outputTelemetryBufferSize == 0 && outputTelemetryBufferTrigger == 0x7E); -} - -// TODO merge it with S.PORT update function when finished void sportOutputPushPacket(SportTelemetryPacket * packet) { uint16_t crc = 0; @@ -77,285 +48,7 @@ void sportOutputPushPacket(SportTelemetryPacket * packet) crc &= 0x00ff; } - telemetryOutputPushByte(0xFF-crc); - telemetryOutputSetTrigger(packet->raw[0]); // physicalId -} - -void sportProcessUpdatePacket(uint8_t * packet) -{ - if (packet[0]==0x5E && packet[1]==0x50) { - switch (packet[2]) { - case PRIM_ACK_POWERUP : - if (sportUpdateState == SPORT_POWERUP_REQ) { - sportUpdateState = SPORT_POWERUP_ACK; - } - break; - - case PRIM_ACK_VERSION: - if (sportUpdateState == SPORT_VERSION_REQ) { - sportUpdateState = SPORT_VERSION_ACK; - // SportVersion[0] = packet[3] ; - // SportVersion[1] = packet[4] ; - // SportVersion[2] = packet[5] ; - // SportVersion[3] = packet[6] ; - // SportVerValid = 1 ; - } - break; - - case PRIM_REQ_DATA_ADDR : - if (sportUpdateState == SPORT_DATA_TRANSFER) { - sportUpdateAddr = *((uint32_t *)(&packet[3])); - sportUpdateState = SPORT_DATA_REQ; - } - break; - - case PRIM_END_DOWNLOAD : - sportUpdateState = SPORT_COMPLETE ; - break; - - case PRIM_DATA_CRC_ERR : - sportUpdateState = SPORT_FAIL ; - break; - } - } -} - -bool sportWaitState(SportUpdateState state, int timeout) -{ -#if defined(SIMU) - UNUSED(state); - UNUSED(timeout); - return true; -#else - watchdogSuspend(timeout / 10); - for (int i=timeout/2; i>=0; i--) { - uint8_t byte ; - while (telemetryGetByte(&byte)) { - processFrskyTelemetryData(byte); - } - if (sportUpdateState == state) { - return true; - } - else if (sportUpdateState == SPORT_FAIL) { - return false; - } - RTOS_WAIT_TICKS(1); - } - return false; -#endif -} - -void sportClearPacket(uint8_t * packet) -{ - memset(packet+2, 0, 6); -} - -// TODO merge this function -void sportWritePacket(uint8_t * packet) -{ - uint8_t * ptr = outputTelemetryBuffer; - *ptr++ = 0x7E; - *ptr++ = 0xFF; - packet[7] = crc16(packet, 7); - for (int i=0; i<8; i++) { - if (packet[i] == 0x7E || packet[i] == 0x7D) { - *ptr++ = 0x7D; - *ptr++ = 0x20 ^ packet[i]; - } - else { - *ptr++ = packet[i]; - } - } - sportSendBuffer(outputTelemetryBuffer, ptr-outputTelemetryBuffer); -} - -const char * sportUpdatePowerOn(ModuleIndex module) -{ - uint8_t packet[8]; - - sportUpdateState = SPORT_POWERUP_REQ; - sportWaitState(SPORT_IDLE, 500); // Clear the fifo - - telemetryInit(PROTOCOL_FRSKY_SPORT); - -#if defined(PCBTARANIS) || defined(PCBHORUS) - if (module == INTERNAL_MODULE) - INTERNAL_MODULE_ON(); - else if (module == EXTERNAL_MODULE) - EXTERNAL_MODULE_ON(); - else - SPORT_UPDATE_POWER_ON(); -#endif - - sportWaitState(SPORT_IDLE, 50); // Clear the fifo - - for (int i=0; i<10; i++) { - // max 10 attempts - sportClearPacket(packet); - packet[0] = 0x50 ; - packet[1] = PRIM_REQ_POWERUP; - sportWritePacket(packet); - if (sportWaitState(SPORT_POWERUP_ACK, 100)) - return NULL; - } - - if (telemetryProtocol != PROTOCOL_FRSKY_SPORT) { - return TR("Not responding", "Not S.Port 1"); - } - - if (!IS_FRSKY_SPORT_PROTOCOL()) { - return TR("Not responding", "Not S.Port 2"); - } -#if defined(PCBX7) - if (IS_PCBREV_40()) { - return TR("Bottom pin no resp", "Bottom pin not responding"); - } - else { - return TR("Module pin no resp", "Module pin not responding"); - } -#else - return TR("Not responding", "Module not responding"); -#endif -} - -const char * sportUpdateReqVersion() -{ - uint8_t packet[8]; - sportWaitState(SPORT_IDLE, 20); // Clear the fifo - sportUpdateState = SPORT_VERSION_REQ; - for (int i=0; i<10; i++) { - // max 10 attempts - sportClearPacket(packet) ; - packet[0] = 0x50 ; - packet[1] = PRIM_REQ_VERSION ; - sportWritePacket(packet); - if (sportWaitState(SPORT_VERSION_ACK, 200)) - return NULL; - } - return "Version request failed"; -} - -const char * sportUpdateUploadFile(const char *filename) -{ - FIL file; - uint32_t buffer[1024/4]; - UINT count; - uint8_t packet[8]; - - if (f_open(&file, filename, FA_READ) != FR_OK) { - return "Error opening file"; - } - - sportWaitState(SPORT_IDLE, 200); // Clear the fifo - sportUpdateState = SPORT_DATA_TRANSFER; - sportClearPacket(packet) ; - packet[0] = 0x50 ; - packet[1] = PRIM_CMD_DOWNLOAD ; - // Stop here for testing - sportWritePacket(packet); - - while(1) { - if (f_read(&file, buffer, 1024, &count) != FR_OK) { - f_close(&file); - return "Error reading file"; - } - - count >>= 2; - - for (UINT i=0; i> 2; // 32 bit word offset into buffer - uint32_t *data = (uint32_t *)(&packet[2]); - *data = buffer[offset]; - sportUpdateState = SPORT_DATA_TRANSFER, - sportWritePacket(packet); - if (i==0) { - drawProgressBar(STR_WRITING, file.fptr, file.obj.objsize); - } - } - - if (count < 256) { - f_close(&file); - return NULL; - } - } -} - -const char * sportUpdateEnd() -{ - uint8_t packet[8]; - if (!sportWaitState(SPORT_DATA_REQ, 2000)) - return "Module refused data"; - sportClearPacket(packet); - packet[0] = 0x50 ; - packet[1] = PRIM_DATA_EOF; - sportWritePacket(packet); - if (!sportWaitState(SPORT_COMPLETE, 2000)) { - return "Module rejected firmware"; - } - return NULL; -} - -void sportFlashDevice(ModuleIndex module, const char * filename) -{ - pausePulses(); - -#if defined(PCBTARANIS) || defined(PCBHORUS) - uint8_t intPwr = IS_INTERNAL_MODULE_ON(); - uint8_t extPwr = IS_EXTERNAL_MODULE_ON(); - INTERNAL_MODULE_OFF(); - EXTERNAL_MODULE_OFF(); - SPORT_UPDATE_POWER_OFF(); - - /* wait 2s off */ - watchdogSuspend(2000); - RTOS_WAIT_MS(2000); -#endif - - const char * result = sportUpdatePowerOn(module); - if (!result) result = sportUpdateReqVersion(); - if (!result) result = sportUpdateUploadFile(filename); - if (!result) result = sportUpdateEnd(); - - if (result) { - POPUP_WARNING(STR_FIRMWARE_UPDATE_ERROR); - SET_WARNING_INFO(result, strlen(result), 0); - } - -#if defined(PCBTARANIS) || defined(PCBHORUS) - INTERNAL_MODULE_OFF(); - EXTERNAL_MODULE_OFF(); - SPORT_UPDATE_POWER_OFF(); -#endif - - sportWaitState(SPORT_IDLE, 500); // Clear the fifo - -#if defined(PCBTARANIS) || defined(PCBHORUS) - if (intPwr) - INTERNAL_MODULE_ON(); - if (extPwr) - EXTERNAL_MODULE_ON(); -#endif - - sportUpdateState = SPORT_IDLE; - - resumePulses(); -} -#endif - -void sportProcessPacket(uint8_t * packet) -{ -#if defined(STM32) - if (sportUpdateState != SPORT_IDLE) { - sportProcessUpdatePacket(packet); // Uses different chksum - return; - } -#endif - - sportProcessTelemetryPacket(packet); + outputTelemetryBuffer.push(0xFF - crc); + outputTelemetryBuffer.setTrigger(packet->raw[0]); // physicalId + outputTelemetryBuffer.setDestination(SPORT_MODULE); } diff --git a/radio/src/io/io_arm.h b/radio/src/io/frsky_sport.h similarity index 84% rename from radio/src/io/io_arm.h rename to radio/src/io/frsky_sport.h index d510add9b..57a7dabf7 100644 --- a/radio/src/io/io_arm.h +++ b/radio/src/io/frsky_sport.h @@ -18,8 +18,8 @@ * GNU General Public License for more details. */ -#ifndef _IO_ARM_H_ -#define _IO_ARM_H_ +#ifndef _IO_FRSKY_SPORT_H_ +#define _IO_FRSKY_SPORT_H_ #include "dataconstants.h" @@ -35,15 +35,13 @@ PACK(union SportTelemetryPacket uint8_t raw[8]; }); -void sportProcessPacket(uint8_t * packet); -bool isSportOutputBufferAvailable(); +bool isTelemetryOutputBufferAvailable(); void sportOutputPushPacket(SportTelemetryPacket * packet); -void sportFlashDevice(ModuleIndex module, const char * filename); #endif #if defined(STM32) bool isBootloader(const char * filename); void bootloaderFlash(const char * filename); #endif - -#endif // _IO_ARM_H_ + +#endif // _IO_FRSKY_SPORT_H_ diff --git a/radio/src/keys.h b/radio/src/keys.h index 3b78a8475..8c2983637 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -21,6 +21,9 @@ #ifndef _KEYS_H_ #define _KEYS_H_ +#include +#include "board.h" + #define EVT_KEY_MASK(e) ((e) & 0x1f) #if defined(PCBHORUS) diff --git a/radio/src/logs.cpp b/radio/src/logs.cpp index f5fcda516..8a90c71c1 100644 --- a/radio/src/logs.cpp +++ b/radio/src/logs.cpp @@ -71,7 +71,7 @@ const char * logsOpen() len = i+1; if (len) { if (filename[i]) - filename[i] = idx2char(filename[i]); + filename[i] = zchar2char(filename[i]); else filename[i] = '_'; } @@ -170,6 +170,10 @@ void writeHeader() #define STR_SWITCHES_LOG_HEADER "SA,SB,SC,SD,SF,SH" #elif defined(PCBXLITE) #define STR_SWITCHES_LOG_HEADER "SA,SB,SC,SD" +#elif defined(PCBXLITES) + #define STR_SWITCHES_LOG_HEADER "SA,SB,SC,SD,SE,SF" +#elif defined(PCBX3) + #define STR_SWITCHES_LOG_HEADER "SA,SB,SC,SE,SF" #else #define STR_SWITCHES_LOG_HEADER "SA,SB,SC,SD,SE,SF,SG,SH" #endif @@ -270,7 +274,16 @@ void logsWrite() } // TODO: use hardware config to populate -#if defined(PCBXLITE) +#if defined(PCBX3) +f_printf(&g_oLogFile, "%d,%d,%d,%d,0x%08X%08X,", + GET_3POS_STATE(SA), + GET_3POS_STATE(SB), + GET_3POS_STATE(SC), + GET_2POS_STATE(SE), + GET_2POS_STATE(SF), + getLogicalSwitchesStates(32), + getLogicalSwitchesStates(0)); +#elif defined(PCBXLITE) f_printf(&g_oLogFile, "%d,%d,%d,%d,0x%08X%08X,", GET_3POS_STATE(SA), GET_3POS_STATE(SB), diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt index b653aa49e..398063f0d 100644 --- a/radio/src/lua/CMakeLists.txt +++ b/radio/src/lua/CMakeLists.txt @@ -40,6 +40,7 @@ set(LUA_INCLUDES_STM32F4 ) if(PYTHONINTERP_FOUND) + add_lua_export_target(x3 ${LUA_INCLUDES_STM32F2} -DPCBTARANIS -DPCBX3) add_lua_export_target(x7 ${LUA_INCLUDES_STM32F2} -DPCBTARANIS -DPCBX7) add_lua_export_target(xlite ${LUA_INCLUDES_STM32F2} -DPCBTARANIS -DPCBXLITE) add_lua_export_target(x9d ${LUA_INCLUDES_STM32F2} -DPCBTARANIS -DPCBX9D) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index be543535f..d5dd29919 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -33,6 +33,8 @@ #include "lua/lua_exports_x9e.inc" #elif defined(PCBX7) #include "lua/lua_exports_x7.inc" +#elif defined(PCBX3) + #include "lua/lua_exports_x3.inc" #elif defined(PCBXLITE) #include "lua/lua_exports_xlite.inc" #elif defined(PCBTARANIS) @@ -420,9 +422,9 @@ When called without parameters, it will only return the status of the output buf static int luaSportTelemetryPush(lua_State * L) { if (lua_gettop(L) == 0) { - lua_pushboolean(L, isSportOutputBufferAvailable()); + lua_pushboolean(L, isTelemetryOutputBufferAvailable()); } - else if (isSportOutputBufferAvailable()) { + else if (isTelemetryOutputBufferAvailable()) { SportTelemetryPacket packet; packet.physicalId = getDataId(luaL_checkunsigned(L, 1)); packet.primId = luaL_checkunsigned(L, 2); @@ -437,6 +439,63 @@ static int luaSportTelemetryPush(lua_State * L) return 1; } +#if defined(PXX2) +/*luadoc +@function pxx2TelemetryPush() + +This functions allows for sending SPORT telemetry data toward the receiver, +and more generally, to anything connected SPORT bus on the receiver or transmitter. + +When called without parameters, it will only return the status of the output buffer without sending anything. + +@param module module index + +@param receiver receiver index + +@param sensorId physical sensor ID + +@param frameId frame ID + +@param dataId data ID + +@param value value + +@retval boolean data queued in output buffer or not. + +@status current Introduced in 2.3.0 +*/ +static int luaPXX2TelemetryPush(lua_State * L) +{ + if (lua_gettop(L) == 0) { + lua_pushboolean(L, isTelemetryOutputBufferAvailable()); + } + else if (isTelemetryOutputBufferAvailable()) { + SportTelemetryPacket packet; + uint8_t module = getDataId(luaL_checkunsigned(L, 1)); + uint8_t receiver = getDataId(luaL_checkunsigned(L, 2)); + uint8_t rx_uid = g_model.moduleData[module].pxx2.getReceiverSlot(receiver); + if (rx_uid > 0) { + // TODO add more controls (module started, module = PXX2, etc.) + packet.physicalId = getDataId(luaL_checkunsigned(L, 3)); + packet.primId = luaL_checkunsigned(L, 4); + packet.dataId = luaL_checkunsigned(L, 5); + packet.value = luaL_checkunsigned(L, 6); + // TODO we could avoid this new copy + pushPXX2TelemetryPacket(module, rx_uid - 1, &packet); + lua_pushboolean(L, true); + } + else { + lua_pushboolean(L, false); + } + } + else { + lua_pushboolean(L, false); + } + return 1; +} +#endif + +#if defined(CROSSFIRE) /*luadoc @function crossfireTelemetryPop() @@ -518,6 +577,7 @@ static int luaCrossfireTelemetryPush(lua_State * L) } return 1; } +#endif /*luadoc @function getFieldInfo(name) @@ -931,55 +991,6 @@ static int luaGetGeneralSettings(lua_State * L) return 1; } -/*luadoc -@function popupInput(title, event, input, min, max) - -Raises a pop-up on screen that allows uses input - -@param title (string) text to display - -@param event (number) the event variable that is passed in from the -Run function (key pressed) - -@param input (number) value that can be adjusted by the +/­- keys - -@param min (number) min value that input can reach (by pressing the -­ key) - -@param max (number) max value that input can reach - -@retval number result of the input adjustment - -@retval "OK" user pushed ENT key - -@retval "CANCEL" user pushed EXIT key - -@notice Use only from stand-alone and telemetry scripts. - -@status current Introduced in 2.0.0 -*/ -static int luaPopupInput(lua_State * L) -{ - event_t event = luaL_checkinteger(L, 2); - warningInputValue = luaL_checkinteger(L, 3); - warningInputValueMin = luaL_checkinteger(L, 4); - warningInputValueMax = luaL_checkinteger(L, 5); - warningText = luaL_checkstring(L, 1); - warningType = WARNING_TYPE_INPUT; - runPopupWarning(event); - if (warningResult) { - warningResult = 0; - lua_pushstring(L, "OK"); - } - else if (!warningText) { - lua_pushstring(L, "CANCEL"); - } - else { - lua_pushinteger(L, warningInputValue); - } - warningText = NULL; - return 1; -} - /*luadoc @function popupWarning(title, event) @@ -1339,7 +1350,7 @@ const luaL_Reg opentxLib[] = { { "playDuration", luaPlayDuration }, { "playTone", luaPlayTone }, { "playHaptic", luaPlayHaptic }, - { "popupInput", luaPopupInput }, + // { "popupInput", luaPopupInput }, { "popupWarning", luaPopupWarning }, { "popupConfirmation", luaPopupConfirmation }, { "defaultStick", luaDefaultStick }, @@ -1355,6 +1366,10 @@ const luaL_Reg opentxLib[] = { { "sportTelemetryPop", luaSportTelemetryPop }, { "sportTelemetryPush", luaSportTelemetryPush }, { "setTelemetryValue", luaSetTelemetryValue }, +#if defined(PXX2) + { "sportTelemetryPop", luaSportTelemetryPop }, + { "pxx2TelemetryPush", luaPXX2TelemetryPush }, +#endif #if defined(CROSSFIRE) { "crossfireTelemetryPop", luaCrossfireTelemetryPop }, { "crossfireTelemetryPush", luaCrossfireTelemetryPush }, @@ -1388,11 +1403,11 @@ const luaR_value_entry opentxConstants[] = { { "MIXSRC_SB", MIXSRC_SB }, { "MIXSRC_SC", MIXSRC_SC }, { "MIXSRC_SD", MIXSRC_SD }, -#if !defined(PCBX7) && !defined(PCBXLITE) +#if !defined(PCBX7) && !defined(PCBXLITE) && !defined(PCBX3) { "MIXSRC_SE", MIXSRC_SE }, { "MIXSRC_SG", MIXSRC_SG }, #endif -#if !defined(PCBXLITE) +#if !defined(PCBXLITE) && !defined(PCBX3) { "MIXSRC_SF", MIXSRC_SF }, { "MIXSRC_SH", MIXSRC_SH }, #endif diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index 235e83afa..cd035720c 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -671,10 +671,10 @@ bool luaLoadTelemetryScript(uint8_t index) ScriptInternalData & sid = scriptInternalData[luaScriptsCount++]; sid.reference = SCRIPT_TELEMETRY_FIRST+index; sid.state = SCRIPT_NOFILE; - char filename[sizeof(SCRIPTS_TELEM_PATH)+sizeof(script.file)+sizeof(SCRIPT_EXT)] = SCRIPTS_TELEM_PATH "/"; - strncpy(filename+sizeof(SCRIPTS_TELEM_PATH), script.file, sizeof(script.file)); - filename[sizeof(SCRIPTS_TELEM_PATH)+sizeof(script.file)] = '\0'; - strcat(filename+sizeof(SCRIPTS_TELEM_PATH), SCRIPT_EXT); + char filename[sizeof(SCRIPTS_TELEM_PATH) + LEN_SCRIPT_FILENAME + sizeof(SCRIPT_EXT)] = SCRIPTS_TELEM_PATH "/"; + strncpy(filename + sizeof(SCRIPTS_TELEM_PATH), script.file, LEN_SCRIPT_FILENAME); + filename[sizeof(SCRIPTS_TELEM_PATH) + LEN_SCRIPT_FILENAME] = '\0'; + strcat(filename + sizeof(SCRIPTS_TELEM_PATH), SCRIPT_EXT); if (luaLoad(lsScripts, filename, sid) == SCRIPT_PANIC) { return false; } @@ -733,7 +733,7 @@ void luaLoadPermanentScripts() void displayLuaError(const char * title) { #if !defined(COLORLCD) - DRAW_MESSAGE_BOX(title); + drawMessageBox(title); #endif if (lua_warning_info[0]) { char * split = strstr(lua_warning_info, ": "); diff --git a/radio/src/main_arm.cpp b/radio/src/main.cpp similarity index 87% rename from radio/src/main_arm.cpp rename to radio/src/main.cpp index 5b601ff5a..7a088558e 100644 --- a/radio/src/main_arm.cpp +++ b/radio/src/main.cpp @@ -50,7 +50,7 @@ void handleUsbConnection() } } if (!usbStarted() && usbPlugged() && getSelectedUsbMode() == USB_UNSELECTED_MODE) { - if((g_eeGeneral.USBMode == USB_UNSELECTED_MODE) && (popupMenuNoItems == 0)) { + if((g_eeGeneral.USBMode == USB_UNSELECTED_MODE) && (popupMenuItemsCount == 0)) { POPUP_MENU_ADD_ITEM(STR_USB_JOYSTICK); POPUP_MENU_ADD_ITEM(STR_USB_MASS_STORAGE); #if defined(DEBUG) @@ -74,6 +74,76 @@ void handleUsbConnection() #endif // defined(STM32) && !defined(SIMU) } +#if defined(JACK_DETECT_GPIO) && !defined(SIMU) +bool isJackPlugged() +{ + // debounce + static bool debounced_state = 0; + static bool last_state = 0; + + if (GPIO_ReadInputDataBit(JACK_DETECT_GPIO, JACK_DETECT_GPIO_PIN)) { + if (!last_state) { + debounced_state = false; + } + last_state = false; + } + else { + if (last_state) { + debounced_state = true; + } + last_state = true; + } + return debounced_state; +} +#endif + +#if defined(PCBXLITES) +uint8_t jackState = SPEAKER_ACTIVE; + +const char STR_JACK_HEADPHONE[] = "Headphone"; +const char STR_JACK_TRAINER[] = "Trainer"; + +void onJackConnectMenu(const char * result) +{ + if (result == STR_JACK_HEADPHONE) { + jackState = HEADPHONE_ACTIVE; + disableSpeaker(); + enableHeadphone(); + } + else if (result == STR_JACK_TRAINER) { + jackState = TRAINER_ACTIVE; + enableTrainer(); + } +} + +void handleJackConnection() +{ + if (jackState == SPEAKER_ACTIVE && isJackPlugged()) { + if (g_eeGeneral.jackMode == JACK_HEADPHONE_MODE) { + jackState = HEADPHONE_ACTIVE; + disableSpeaker(); + enableHeadphone(); + } + else if (g_eeGeneral.jackMode == JACK_TRAINER_MODE) { + jackState = TRAINER_ACTIVE; + enableTrainer(); + } + else if (popupMenuItemsCount == 0) { + POPUP_MENU_ADD_ITEM(STR_JACK_HEADPHONE); + POPUP_MENU_ADD_ITEM(STR_JACK_TRAINER); + POPUP_MENU_START(onJackConnectMenu); + } + } + else if (jackState == SPEAKER_ACTIVE && !isJackPlugged() && popupMenuItemsCount > 0 && popupMenuHandler == onJackConnectMenu) { + popupMenuItemsCount = 0; + } + else if (jackState != SPEAKER_ACTIVE && !isJackPlugged()) { + jackState = SPEAKER_ACTIVE; + enableSpeaker(); + } +} +#endif + void checkSpeakerVolume() { if (currentSpeakerVolume != requiredSpeakerVolume) { @@ -227,7 +297,7 @@ void guiMain(event_t evt) while (1) { // normal GUI from menus const char * warn = warningText; - uint8_t menu = popupMenuNoItems; + uint8_t menu = popupMenuItemsCount; static bool popupDisplayed = false; if (warn || menu) { @@ -243,7 +313,7 @@ void guiMain(event_t evt) if (warn) DISPLAY_WARNING(evt); if (menu) { const char * result = runPopupMenu(evt); - if (result) { + if (popupMenuItemsCount == 0) { popupMenuHandler(result); if (menuEvent == 0) { evt = EVT_REFRESH; @@ -330,8 +400,6 @@ void handleGui(event_t event) { } } -bool inPopupMenu = false; - void guiMain(event_t evt) { #if defined(LUA) @@ -373,13 +441,9 @@ void guiMain(event_t evt) handleGui(0); // suppress events, they are handled by the warning DISPLAY_WARNING(evt); } - else if (popupMenuNoItems > 0) { + else if (popupMenuItemsCount > 0) { // popup menu is active display it on top of normal menus handleGui(0); // suppress events, they are handled by the popup - if (!inPopupMenu) { - TRACE("Popup Menu started"); - inPopupMenu = true; - } const char * result = runPopupMenu(evt); if (result) { TRACE("popupMenuHandler(%s)", result); @@ -388,10 +452,6 @@ void guiMain(event_t evt) } else { // normal menus - if (inPopupMenu) { - TRACE("Popup Menu ended"); - inPopupMenu = false; - } handleGui(evt); } @@ -409,6 +469,9 @@ void perMain() checkEeprom(); logsWrite(); handleUsbConnection(); +#if defined(PCBXLITES) + handleJackConnection(); +#endif checkTrainerSettings(); periodicTick(); DEBUG_TIMER_STOP(debugTimerPerMain1); diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index b94181454..edfa31aca 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -347,7 +347,7 @@ getvalue_t getValue(mixsrc_t i) 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 : (switchState(3*sw+1) ? 0 : 1024)); + return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024)); } else { return 0; diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index e21595ce0..34d7e7072 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -23,40 +23,27 @@ #include "datastructs.h" -#define WARN_THR_BIT 0x01 -#define WARN_BEP_BIT 0x80 -#define WARN_SW_BIT 0x02 -#define WARN_MEM_BIT 0x04 -#define WARN_BVAL_BIT 0x38 +#define EEPROM_VER 219 +#define FIRST_CONV_EEPROM_VER 216 -#define WARN_THR (!(g_eeGeneral.warnOpts & WARN_THR_BIT)) -#define WARN_BEP (!(g_eeGeneral.warnOpts & WARN_BEP_BIT)) -#define WARN_SW (!(g_eeGeneral.warnOpts & WARN_SW_BIT)) -#define WARN_MEM (!(g_eeGeneral.warnOpts & WARN_MEM_BIT)) -#define BEEP_VAL ( (g_eeGeneral.warnOpts & WARN_BVAL_BIT) >>3 ) - - #define EEPROM_VER 218 - #define FIRST_CONV_EEPROM_VER 216 - -#define GET_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol -#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted -#define GET_PPM_DELAY(idx) (g_model.moduleData[idx].ppm.delay * 50 + 300) -#define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppm.frameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount) +#define GET_MODULE_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol +#define GET_TRAINER_PPM_POLARITY() g_model.trainerData.pulsePol +#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted +#define GET_MODULE_PPM_DELAY(idx) (g_model.moduleData[idx].ppm.delay * 50 + 300) +#define GET_TRAINER_PPM_DELAY(idx) (g_model.trainerData.delay * 50 + 300) +#define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppm.frameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount) #if defined(PCBHORUS) #define IS_TRAINER_EXTERNAL_MODULE() false #define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.serial2Mode==UART_MODE_SBUS_TRAINER) #elif defined(PCBTARANIS) - #define IS_TRAINER_EXTERNAL_MODULE() (g_model.trainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || g_model.trainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) - #define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.serial2Mode==UART_MODE_SBUS_TRAINER) + #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.serial2Mode==UART_MODE_SBUS_TRAINER) #else #define IS_TRAINER_EXTERNAL_MODULE() false #endif - #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE) - - #define IS_PLAY_BOTH_FUNC(func) (0) - #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME) +#define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE) #if defined(GVARS) #define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR) @@ -141,21 +128,20 @@ enum CurveRefType { CURVE_REF_CUSTOM }; - #define MIN_EXPO_WEIGHT -100 #define EXPO_VALID(ed) ((ed)->mode) #define EXPO_MODE_ENABLE(ed, v) (((v)<0 && ((ed)->mode&1)) || ((v)>=0 && ((ed)->mode&2))) - #define limit_min_max_t int16_t - #define LIMIT_EXT_PERCENT 150 - #define LIMIT_EXT_MAX (LIMIT_EXT_PERCENT*10) - #define PPM_CENTER_MAX 500 - #define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->max+1000) - #define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->min-1000) - #define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR_PREC1(lim->offset, -1000, 1000, mixerCurrentFlightMode) : lim->offset) - #define LIMIT_MAX_RESX(lim) calc1000toRESX(LIMIT_MAX(lim)) - #define LIMIT_MIN_RESX(lim) calc1000toRESX(LIMIT_MIN(lim)) - #define LIMIT_OFS_RESX(lim) calc1000toRESX(LIMIT_OFS(lim)) +#define limit_min_max_t int16_t +#define LIMIT_EXT_PERCENT 150 +#define LIMIT_EXT_MAX (LIMIT_EXT_PERCENT*10) +#define PPM_CENTER_MAX 500 +#define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->max+1000) +#define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -GV_RANGELARGE, GV_RANGELARGE) ? GET_GVAR_PREC1(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, mixerCurrentFlightMode) : lim->min-1000) +#define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR_PREC1(lim->offset, -1000, 1000, mixerCurrentFlightMode) : lim->offset) +#define LIMIT_MAX_RESX(lim) calc1000toRESX(LIMIT_MAX(lim)) +#define LIMIT_MIN_RESX(lim) calc1000toRESX(LIMIT_MIN(lim)) +#define LIMIT_OFS_RESX(lim) calc1000toRESX(LIMIT_OFS(lim)) #define TRIM_OFF (1) #define TRIM_ON (0) @@ -191,8 +177,6 @@ enum CurveRefType { #define MD_OFFSET(md) (md->offset) #define MD_OFFSET_TO_UNION(md, var) var.word = md->offset #define MD_UNION_TO_OFFSET(var, md) md->offset = var.word -// #define MD_SETOFFSET(md, val) md->offset = val - enum LogicalSwitchesFunctions { LS_FUNC_NONE, @@ -222,14 +206,6 @@ enum LogicalSwitchesFunctions { #define MAX_LS_DELAY 250 /*25s*/ #define MAX_LS_ANDSW SWSRC_LAST -//#define TELEM_FLAG_TIMEOUT 0x01 -#define TELEM_FLAG_LOG 0x02 -//#define TELEM_FLAG_PERSISTENT 0x04 -//#define TELEM_FLAG_SCALE 0x08 -#define TELEM_FLAG_AUTO_OFFSET 0x10 -#define TELEM_FLAG_FILTER 0x20 -#define TELEM_FLAG_LOSS_ALARM 0x40 - enum TelemetrySensorType { TELEM_TYPE_CUSTOM, @@ -251,16 +227,10 @@ enum TelemetrySensorFormula }; enum VarioSource { -#if !defined(TELEMETRY_FRSKY_SPORT) - VARIO_SOURCE_ALTI, - VARIO_SOURCE_ALTI_PLUS, -#endif VARIO_SOURCE_VSPEED, VARIO_SOURCE_A1, VARIO_SOURCE_A2, -#if defined(TELEMETRY_FRSKY_SPORT) VARIO_SOURCE_DTE, -#endif VARIO_SOURCE_COUNT, VARIO_SOURCE_LAST = VARIO_SOURCE_COUNT-1 }; @@ -292,8 +262,6 @@ enum FrskyVoltsSource { FRSKY_VOLTS_SOURCE_LAST=FRSKY_VOLTS_SOURCE_CELLS }; - - enum SwashType { SWASH_TYPE_NONE, SWASH_TYPE_120, @@ -310,8 +278,8 @@ enum SwashType { #define ROTARY_ENCODER_MAX 1024 - #define TRIMS_ARRAY_SIZE 8 - #define TRIM_MODE_NONE 0x1F // 0b11111 +#define TRIMS_ARRAY_SIZE 8 +#define TRIM_MODE_NONE 0x1F // 0b11111 #define IS_MANUAL_RESET_TIMER(idx) (g_model.timers[idx].persistent == 2) @@ -321,37 +289,6 @@ enum SwashType { #define TIMER_COUNTDOWN_START(x) 10 #endif -enum Protocols { - PROTO_PPM, -#if defined(PXX) || defined(DSM2) || defined(IRPROTOS) - PROTO_PXX, -#endif -#if defined(DSM2) || defined(IRPROTOS) - PROTO_DSM2_LP45, - PROTO_DSM2_DSM2, - PROTO_DSM2_DSMX, -#endif - PROTO_CROSSFIRE, -#if defined(IRPROTOS) - // only used on AVR - // we will need 4 bits for proto :( - PROTO_SILV, - PROTO_TRAC09, - PROTO_PICZ, - PROTO_SWIFT, -#endif - PROTO_MULTIMODULE, - PROTO_SBUS, - PROTO_PXX2, - PROTO_NONE -}; - -#if defined(PXX2) -#define PROTO_PXX_EXTERNAL_MODULE PROTO_PXX2 -#else -#define PROTO_PXX_EXTERNAL_MODULE PROTO_PXX -#endif - enum XJTRFProtocols { RF_PROTO_OFF = -1, RF_PROTO_X16, @@ -369,6 +306,21 @@ enum R9MSubTypes MODULE_SUBTYPE_R9M_LAST=MODULE_SUBTYPE_R9M_AUPLUS }; +enum R9MRegion +{ + MODULE_R9M_REGION_FCC, + MODULE_R9M_REGION_EU, + MODULE_R9M_REGION_FLEX, + MODULE_R9M_REGION_LAST=MODULE_R9M_REGION_FLEX +}; + +enum R9MFrenquency +{ + MODULE_R9M_FREQ_868MHZ, + MODULE_R9M_FREQ_915MHZ, + MODULE_R9M_FREQ_LAST=MODULE_R9M_FREQ_915MHZ +}; + enum MultiModuleRFProtocols { MM_RF_PROTO_CUSTOM = -1, MM_RF_PROTO_FIRST = MM_RF_PROTO_CUSTOM, @@ -450,11 +402,17 @@ enum ModuleTypes { MODULE_TYPE_NONE = 0, MODULE_TYPE_PPM, MODULE_TYPE_XJT, + MODULE_TYPE_XJT2, MODULE_TYPE_DSM2, MODULE_TYPE_CROSSFIRE, MODULE_TYPE_MULTIMODULE, MODULE_TYPE_R9M, + MODULE_TYPE_R9M2, + MODULE_TYPE_R9M_LITE, + MODULE_TYPE_R9M_LITE2, + MODULE_TYPE_R9M_LITE_PRO2, MODULE_TYPE_SBUS, + MODULE_TYPE_MAX = MODULE_TYPE_SBUS, MODULE_TYPE_COUNT }; @@ -498,17 +456,18 @@ enum ThrottleSources { THROTTLE_SOURCE_CH1, }; -enum TelemetryType +enum TelemetryProtocols { PROTOCOL_TELEMETRY_FIRST, - PROTOCOL_FRSKY_SPORT = PROTOCOL_TELEMETRY_FIRST, - PROTOCOL_FRSKY_D, - PROTOCOL_FRSKY_D_SECONDARY, - PROTOCOL_PULSES_CROSSFIRE, - PROTOCOL_SPEKTRUM, - PROTOCOL_FLYSKY_IBUS, - PROTOCOL_MULTIMODULE, - PROTOCOL_TELEMETRY_LAST=PROTOCOL_MULTIMODULE + PROTOCOL_TELEMETRY_FRSKY_SPORT = PROTOCOL_TELEMETRY_FIRST, + PROTOCOL_TELEMETRY_FRSKY_D, + PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY, + PROTOCOL_TELEMETRY_CROSSFIRE, + PROTOCOL_TELEMETRY_SPEKTRUM, + PROTOCOL_TELEMETRY_FLYSKY_IBUS, + PROTOCOL_TELEMETRY_MULTIMODULE, + PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_MULTIMODULE, + PROTOCOL_TELEMETRY_PXX2, }; enum DisplayTrims @@ -518,8 +477,6 @@ enum DisplayTrims DISPLAY_TRIMS_ALWAYS }; -#define TOTAL_EEPROM_USAGE (sizeof(ModelData)*MAX_MODELS + sizeof(RadioData)) - extern RadioData g_eeGeneral; extern ModelData g_model; @@ -531,4 +488,7 @@ PACK(union u_int8int16_t { int16_t word; }); +#define EE_GENERAL 0x01 +#define EE_MODEL 0x02 + #endif // _MYEEPROM_H_ diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index e45eb194c..2aef36ba0 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -27,14 +27,13 @@ ModelData g_model; Clipboard clipboard; #endif - uint8_t unexpectedShutdown = 0; -/* AVR: mixer duration in 1/16ms */ +uint16_t vbattRTC; + /* ARM: mixer duration in 0.5us */ uint16_t maxMixerDuration; - uint8_t heartbeat; #if defined(OVERRIDE_CHANNEL_FUNCTION) @@ -242,16 +241,22 @@ void generalDefault() #elif defined(PCBXLITE) g_eeGeneral.potsConfig = 0x0F; // S1 and S2 = pot without detent #elif defined(PCBX7) - g_eeGeneral.potsConfig = 0x07; // S1 = pot without detent, S2 = pot with detent + g_eeGeneral.potsConfig = (POT_WITHOUT_DETENT << 0) + (POT_WITH_DETENT << 2); // S1 = pot without detent, S2 = pot with detent +#elif defined(PCBX3) + g_eeGeneral.potsConfig = (POT_WITH_DETENT << 0); // S1 = pot with detent #elif defined(PCBTARANIS) g_eeGeneral.potsConfig = 0x05; // S1 and S2 = pots with detent g_eeGeneral.slidersConfig = 0x03; // LS and RS = sliders with detent #endif -#if defined(PCBXLITE) - g_eeGeneral.switchConfig = (SWITCH_2POS << 6) + (SWITCH_2POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); // 2x3POS, 2x2POS +#if defined(PCBXLITES) + g_eeGeneral.switchConfig = (SWITCH_TOGGLE << 10) + (SWITCH_TOGGLE << 8) + (SWITCH_2POS << 6) + (SWITCH_2POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); +#elif defined(PCBXLITE) + g_eeGeneral.switchConfig = (SWITCH_2POS << 6) + (SWITCH_2POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); #elif defined(PCBX7) g_eeGeneral.switchConfig = 0x000006ff; // 4x3POS, 1x2POS, 1xTOGGLE +#elif defined(PCBX3) + g_eeGeneral.switchConfig = (SWITCH_TOGGLE << 8) + (SWITCH_2POS << 6) + (SWITCH_3POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); #elif defined(PCBTARANIS) || defined(PCBHORUS) g_eeGeneral.switchConfig = 0x00007bff; // 6x3POS, 1x2POS, 1xTOGGLE #endif @@ -300,6 +305,12 @@ void generalDefault() theme->init(); #endif +#if defined(PXX2) + for (uint8_t i=0; imode = 3; // TODO constant #if defined(TRANSLATIONS_CZ) for (int c=0; c<4; c++) { - g_model.inputNames[i][c] = char2idx(STR_INPUTNAMES[1+4*(stick_index-1)+c]); + g_model.inputNames[i][c] = char2zchar(STR_INPUTNAMES[1+4*(stick_index-1)+c]); } #else for (int c=0; c<3; c++) { - g_model.inputNames[i][c] = char2idx(STR_VSRCRAW[2+4*stick_index+c]); + g_model.inputNames[i][c] = char2zchar(STR_VSRCRAW[2 + 4 * stick_index + c]); } #if LEN_INPUT_NAME > 3 g_model.inputNames[i][3] = '\0'; @@ -360,18 +371,21 @@ void applyDefaultTemplate() #if defined(EEPROM) void checkModelIdUnique(uint8_t index, uint8_t module) { + if(isModulePXX(module) && IS_D8_RX(module)) + return; + uint8_t modelId = g_model.header.modelId[module]; uint8_t additionalOnes = 0; - char * name = reusableBuffer.modelsetup.msg; + char * name = reusableBuffer.moduleSetup.msg; - memset(reusableBuffer.modelsetup.msg, 0, sizeof(reusableBuffer.modelsetup.msg)); + memset(reusableBuffer.moduleSetup.msg, 0, sizeof(reusableBuffer.moduleSetup.msg)); if (modelId != 0) { for (uint8_t i = 0; i < MAX_MODELS; i++) { if (i != index) { if (modelId == modelHeaders[i].modelId[module]) { - if ((WARNING_LINE_LEN - 4 - (name - reusableBuffer.modelsetup.msg)) > (signed)(modelHeaders[i].name[0] ? zlen(modelHeaders[i].name, LEN_MODEL_NAME) : sizeof(TR_MODEL) + 2)) { // you cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 (-2 for the ",") - if (reusableBuffer.modelsetup.msg[0] != 0) { + if ((WARNING_LINE_LEN - 4 - (name - reusableBuffer.moduleSetup.msg)) > (signed)(modelHeaders[i].name[0] ? zlen(modelHeaders[i].name, LEN_MODEL_NAME) : sizeof(TR_MODEL) + 2)) { // you cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 (-2 for the ",") + if (reusableBuffer.moduleSetup.msg[0] != 0) { name = strAppend(name, ", "); } if (modelHeaders[i].name[0] == 0) { @@ -396,9 +410,9 @@ void checkModelIdUnique(uint8_t index, uint8_t module) name = strAppend(name, ")"); } - if (reusableBuffer.modelsetup.msg[0] != 0) { + if (reusableBuffer.moduleSetup.msg[0] != 0) { POPUP_WARNING(STR_MODELIDUSED); - SET_WARNING_INFO(reusableBuffer.modelsetup.msg, sizeof(reusableBuffer.modelsetup.msg), 0); + SET_WARNING_INFO(reusableBuffer.moduleSetup.msg, sizeof(reusableBuffer.moduleSetup.msg), 0); } } @@ -447,6 +461,8 @@ void modelDefault(uint8_t id) applyDefaultTemplate(); + memcpy(g_model.modelRegistrationID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID); + #if defined(LUA) && defined(PCBTARANIS) //Horus uses menuModelWizard() for wizard if (isFileAvailable(WIZARD_PATH "/" WIZARD_NAME)) { f_chdir(WIZARD_PATH); @@ -455,14 +471,14 @@ void modelDefault(uint8_t id) #endif #if defined(PCBTARANIS) || defined(PCBHORUS) - g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_XJT; + g_model.moduleData[INTERNAL_MODULE].type = IS_PXX2_INTERNAL_ENABLED() ? MODULE_TYPE_XJT2 : MODULE_TYPE_XJT; g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); #elif defined(PCBSKY9X) g_model.moduleData[EXTERNAL_MODULE].type = MODULE_TYPE_PPM; #endif #if defined(PCBXLITE) - g_model.trainerMode = TRAINER_MODE_MASTER_BLUETOOTH; + g_model.trainerData.mode = TRAINER_MODE_MASTER_BLUETOOTH; #endif #if defined(EEPROM) @@ -702,7 +718,6 @@ void checkBacklight() { static uint8_t tmr10ms ; - uint8_t x = g_blinkTmr10ms; if (tmr10ms != x) { tmr10ms = x; @@ -713,13 +728,12 @@ void checkBacklight() } } - bool backlightOn = (g_eeGeneral.backlightMode == e_backlight_mode_on || lightOffCounter || isFunctionActive(FUNCTION_BACKLIGHT)); + bool backlightOn = (g_eeGeneral.backlightMode == e_backlight_mode_on || (g_eeGeneral.backlightMode != e_backlight_mode_off && lightOffCounter) || isFunctionActive(FUNCTION_BACKLIGHT)); if (flashCounter) backlightOn = !backlightOn; if (backlightOn) BACKLIGHT_ENABLE(); else BACKLIGHT_DISABLE(); - } } @@ -1484,9 +1498,9 @@ void doMixerCalculations() static uint8_t countRangecheck = 0; for (uint8_t i=0; i= MODULE_MODE_BEEP_FIRST) { #endif if (++countRangecheck >= 250) { countRangecheck = 0; @@ -1903,7 +1917,6 @@ void opentxInit(OPENTX_INIT_ARGS) init_trainer_capture(); #endif - startPulses(); wdt_enable(WDTO_500MS); @@ -1926,10 +1939,6 @@ int main() boardInit(); -#if defined(PCBX7) - bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE); //BT is turn on for a brief period to differentiate X7 and X7S -#endif - #if defined(PCBHORUS) loadFonts(); #endif @@ -2031,7 +2040,7 @@ uint32_t pwrCheck() lcdRefreshWait(); lcdClear(); - POPUP_CONFIRMATION(STR_MODEL_SHUTDOWN); + POPUP_CONFIRMATION(STR_MODEL_SHUTDOWN, nullptr); SET_WARNING_INFO(STR_MODEL_STILL_POWERED, sizeof(TR_MODEL_STILL_POWERED), 0); event_t evt = getEvent(false); DISPLAY_WARNING(evt); diff --git a/radio/src/opentx.h b/radio/src/opentx.h index daf616120..acfc457e4 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -190,16 +190,16 @@ #define IS_FAI_FORBIDDEN(idx) (IS_FAI_ENABLED() && isFaiForbidden(idx)) #if defined(BLUETOOTH) -#if defined(X9E) && !defined(USEHORUSBT) - #define IS_BLUETOOTH_TRAINER() (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH) - #define IS_SLAVE_TRAINER() (g_model.trainerMode == TRAINER_MODE_SLAVE) -#else - #define IS_BLUETOOTH_TRAINER() (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH || g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH) - #define IS_SLAVE_TRAINER() (g_model.trainerMode == TRAINER_MODE_SLAVE || g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH) -#endif + #if defined(X9E) && !defined(USEHORUSBT) + #define IS_BLUETOOTH_TRAINER() (g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH) + #define IS_SLAVE_TRAINER() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) + #else + #define IS_BLUETOOTH_TRAINER() (g_model.trainerData.mode == TRAINER_MODE_MASTER_BLUETOOTH || g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH) + #define IS_SLAVE_TRAINER() (g_model.trainerData.mode == TRAINER_MODE_SLAVE || g_model.trainerData.mode == TRAINER_MODE_SLAVE_BLUETOOTH) + #endif #else #define IS_BLUETOOTH_TRAINER() false - #define IS_SLAVE_TRAINER() (g_model.trainerMode == TRAINER_MODE_SLAVE) + #define IS_SLAVE_TRAINER() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) #endif // RESX range is used for internal calculation; The menu says -100.0 to 100.0; internally it is -1024 to 1024 to allow some optimizations @@ -211,6 +211,12 @@ #include "board.h" +#if defined(JACK_DETECT_GPIO) +#define CASE_JACK_DETECT(x) x, +#else +#define CASE_JACK_DETECT(x) +#endif + #if defined(DISK_CACHE) #include "disk_cache.h" #endif @@ -288,7 +294,7 @@ void memswap(void * a, void * b, uint8_t size); #endif #include "fifo.h" -#include "io/io_arm.h" +#include "io/frsky_sport.h" extern volatile tmr10ms_t g_tmr10ms; static inline tmr10ms_t get_tmr10ms() @@ -425,10 +431,11 @@ extern struct t_inactivity inactivity; #endif char hex2zchar(uint8_t hex); -char idx2char(int8_t idx); -int8_t char2idx(char c); +char zchar2char(int8_t idx); +int8_t char2zchar(char c); void str2zchar(char *dest, const char *src, int size); int zchar2str(char *dest, const char *src, int size); +bool cmpStrWithZchar(const char * charString, const char * zcharString, int size); #include "keys.h" #include "pwr.h" @@ -565,6 +572,8 @@ void flightReset(uint8_t check=true); extern uint8_t unexpectedShutdown; +extern uint16_t vbattRTC; + extern uint16_t maxMixerDuration; #define DURATION_MS_PREC2(x) ((x)/20) @@ -651,7 +660,7 @@ uint16_t isqrt32(uint32_t n); #define pauseMixerCalculations() #define resumeMixerCalculations() #else -#include "tasks_arm.h" +#include "tasks.h" extern RTOS_MUTEX_HANDLE mixerMutex; inline void pauseMixerCalculations() { @@ -1034,14 +1043,10 @@ enum AUDIO_SOUNDS { }; #if defined(AUDIO) -#include "audio_arm.h" +#include "audio.h" #endif #include "buzzer.h" - - - - #include "translations.h" #include "fonts.h" @@ -1090,6 +1095,7 @@ void opentxResume(); #else #define SD_SCREEN_FILE_LENGTH 64 #endif + union ReusableBuffer { // ARM 334 bytes @@ -1110,11 +1116,31 @@ union ReusableBuffer struct { char msg[64]; uint8_t r9mPower; - } modelsetup; + union { + struct { + union { + uint8_t registerStep; + uint8_t bindStep; + }; + uint32_t bindWaitTimeout; + uint8_t registerPopupVerticalPosition; + uint8_t registerPopupHorizontalPosition; + int8_t registerPopupEditMode; + char registerRxName[PXX2_LEN_RX_NAME]; + uint8_t registerModuleIndex; + char bindCandidateReceiversNames[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME + 1]; + uint8_t bindCandidateReceiversCount; + uint8_t bindReceiverId; + union { + uint8_t bindSelectedReceiverIndex; + uint8_t shareReceiverId; + }; + } pxx2; + }; + } moduleSetup; // 103 bytes - struct - { + struct { int16_t midVals[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS]; int16_t loVals[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS]; int16_t hiVals[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS]; @@ -1131,8 +1157,7 @@ union ReusableBuffer #if defined(SDCARD) // 274 bytes - struct - { + struct { char lines[NUM_BODY_LINES][SD_SCREEN_FILE_LENGTH+1+1]; // the last char is used to store the flags (directory) of the line uint32_t available; uint16_t offset; @@ -1141,11 +1166,67 @@ union ReusableBuffer } sdmanager; #endif - struct - { + struct { + struct { + int8_t current; + int8_t maximum; + uint8_t timeout; + PXX2HardwareInformation information; + struct { + PXX2HardwareInformation information; + } receivers[PXX2_MAX_RECEIVERS_PER_MODULE]; + } modules[NUM_MODULES]; + + uint32_t updateTime; + + union { + struct { + uint8_t state; // 0x00 = READ 0x40 = WRITE + tmr10ms_t timeout; + uint8_t dirty; + uint8_t rfProtocol; + uint8_t externalAntenna; + int8_t txPower; + } moduleSettings; + + struct { + uint8_t state; // 0x00 = READ 0x40 = WRITE + tmr10ms_t timeout; + uint8_t receiverId; + uint8_t dirty; + uint8_t telemetryDisabled; + uint8_t pwmRate; + uint8_t outputsCount; + uint8_t outputsMapping[24]; + } receiverSettings; + }; + + } hardwareAndSettings; + + struct { uint8_t stickMode; } generalSettings; + struct + { + uint8_t bars[LCD_W]; + uint32_t freq; + uint32_t span; + uint32_t step; + } spectrumAnalyser; + + struct + { + uint32_t freq; + int16_t power; + int16_t peak; + } powerMeter; + + struct + { + int8_t preset; + } curveEdit; + #if defined(STM32) // Data for the USB mass storage driver. If USB mass storage runs no menu is not allowed to be displayed uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET]; @@ -1290,4 +1371,13 @@ extern JitterMeter avgJitter[NUM_ANALOGS]; #include "bluetooth.h" #endif +#if defined(JACK_DETECT_GPIO) +enum JackMode { + JACK_UNSELECTED_MODE, + JACK_HEADPHONE_MODE, + JACK_TRAINER_MODE, + JACK_MAX_MODE = JACK_TRAINER_MODE +}; +#endif + #endif // _OPENTX_H_ diff --git a/radio/src/pulses/crossfire.cpp b/radio/src/pulses/crossfire.cpp index 6f8876913..889bc9140 100644 --- a/radio/src/pulses/crossfire.cpp +++ b/radio/src/pulses/crossfire.cpp @@ -46,3 +46,22 @@ uint8_t createCrossfireChannelsFrame(uint8_t * frame, int16_t * pulses) *buf++ = crc8(crc_start, 23); return buf - frame; } + +void setupPulsesCrossfire() +{ + if (telemetryProtocol == PROTOCOL_TELEMETRY_CROSSFIRE) { + uint8_t * pulses = extmodulePulsesData.crossfire.pulses; +#if defined(LUA) + if (outputTelemetryBufferTrigger != 0x00 && outputTelemetryBufferSize > 0) { + memcpy(pulses, outputTelemetryBuffer, outputTelemetryBufferSize); + extmodulePulsesData.crossfire.length = outputTelemetryBufferSize; + outputTelemetryBufferTrigger = 0x00; + outputTelemetryBufferSize = 0; + } + else +#endif + { + extmodulePulsesData.crossfire.length = createCrossfireChannelsFrame(pulses, &channelOutputs[g_model.moduleData[EXTERNAL_MODULE].channelsStart]); + } + } +} diff --git a/radio/src/pulses/dsm2_arm.cpp b/radio/src/pulses/dsm2.cpp similarity index 65% rename from radio/src/pulses/dsm2_arm.cpp rename to radio/src/pulses/dsm2.cpp index 99b6506b0..306c3b466 100644 --- a/radio/src/pulses/dsm2_arm.cpp +++ b/radio/src/pulses/dsm2.cpp @@ -38,13 +38,13 @@ uint8_t dsm2BindTimer = DSM2_BIND_TIMEOUT; #if defined(PPM_PIN_SERIAL) void putDsm2SerialBit(uint8_t bit) { - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte >>= 1; + extmodulePulsesData.dsm2.serialByte >>= 1; if (bit & 1) { - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte |= 0x80; + extmodulePulsesData.dsm2.serialByte |= 0x80; } - if (++modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount >= 8) { - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0; + if (++extmodulePulsesData.dsm2.serialBitCount >= 8) { + *extmodulePulsesData.dsm2.ptr++ = extmodulePulsesData.dsm2.serialByte; + extmodulePulsesData.dsm2.serialBitCount = 0; } } @@ -69,14 +69,14 @@ void putDsm2Flush() #else void _send_1(uint8_t v) { - if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) + if (extmodulePulsesData.dsm2.index & 1) v += 2; else v -= 2; - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1; - modulePulsesData[EXTERNAL_MODULE].dsm2.index += 1; - modulePulsesData[EXTERNAL_MODULE].dsm2.rest -= v; + *extmodulePulsesData.dsm2.ptr++ = v - 1; + extmodulePulsesData.dsm2.index += 1; + extmodulePulsesData.dsm2.rest -= v; } void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1 @@ -100,35 +100,35 @@ void sendByteDsm2(uint8_t b) // max 10 changes 0 10 10 10 10 1 void putDsm2Flush() { - if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.rest; + if (extmodulePulsesData.dsm2.index & 1) + *extmodulePulsesData.dsm2.ptr++ = extmodulePulsesData.dsm2.rest; else - *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) = modulePulsesData[EXTERNAL_MODULE].dsm2.rest; + *(extmodulePulsesData.dsm2.ptr - 1) = extmodulePulsesData.dsm2.rest; } #endif // This is the data stream to send, prepare after 19.5 mS // Send after 22.5 mS -void setupPulsesDSM2(uint8_t port) +void setupPulsesDSM2() { uint8_t dsmDat[14]; #if defined(PPM_PIN_SERIAL) - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; + extmodulePulsesData.dsm2.serialByte = 0 ; + extmodulePulsesData.dsm2.serialBitCount = 0 ; #else - modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; - modulePulsesData[EXTERNAL_MODULE].dsm2.rest = DSM2_PERIOD * 2000; + extmodulePulsesData.dsm2.index = 0; + extmodulePulsesData.dsm2.rest = DSM2_PERIOD * 2000; #endif - modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses; - switch (s_current_protocol[port]) { - case PROTO_DSM2_LP45: + switch (moduleSettings[EXTERNAL_MODULE].protocol) { + case PROTOCOL_CHANNELS_DSM2_LP45: dsmDat[0] = 0x00; break; - case PROTO_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSM2: dsmDat[0] = 0x10; break; default: // DSMX @@ -140,29 +140,29 @@ void setupPulsesDSM2(uint8_t port) if (dsm2BindTimer > 0) { dsm2BindTimer--; if (switchState(SW_DSM2_BIND)) { - moduleFlag[port] = MODULE_BIND; + moduleSettings[EXTERNAL_MODULE].mode = MODULE_MODE_BIND; dsmDat[0] |= DSM2_SEND_BIND; } } - else if (moduleFlag[port] == MODULE_RANGECHECK) { + else if (moduleSettings[EXTERNAL_MODULE].mode == MODULE_MODE_RANGECHECK) { dsmDat[0] |= DSM2_SEND_RANGECHECK; } else { - moduleFlag[port] = 0; + moduleSettings[EXTERNAL_MODULE].mode = 0; } #else - if (moduleFlag[port] == MODULE_BIND) { + if (moduleSettings[EXTERNAL_MODULE].mode == MODULE_MODE_BIND) { dsmDat[0] |= DSM2_SEND_BIND; } - else if (moduleFlag[port] == MODULE_RANGECHECK) { + else if (moduleSettings[EXTERNAL_MODULE].mode == MODULE_MODE_RANGECHECK) { dsmDat[0] |= DSM2_SEND_RANGECHECK; } #endif - dsmDat[1] = g_model.header.modelId[port]; // DSM2 Header second byte for model match + dsmDat[1] = g_model.header.modelId[EXTERNAL_MODULE]; // DSM2 Header second byte for model match for (int i=0; i>5)+512, 1023); dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03); diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index f15a9968c..d73f367dd 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -22,6 +22,7 @@ #define _MODULES_H_ #include "myeeprom.h" +#include "bitfield.h" #define CROSSFIRE_CHANNELS_COUNT 16 @@ -47,17 +48,21 @@ inline bool isModuleMultimoduleDSM2(uint8_t) } #endif -#if defined(PCBHORUS) || defined(PCBTARANIS) inline bool isModuleXJT(uint8_t idx) { return g_model.moduleData[idx].type == MODULE_TYPE_XJT; } -#else -inline bool isModuleXJT(uint8_t idx) + +inline bool isModuleXJT2(uint8_t idx) { - return idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT; + return g_model.moduleData[idx].type == MODULE_TYPE_XJT2; } -#endif + +inline bool isModuleXJTVariant(uint8_t idx) +{ + return g_model.moduleData[idx].type == MODULE_TYPE_XJT || g_model.moduleData[idx].type == MODULE_TYPE_XJT2; +} + #if defined(CROSSFIRE) inline bool isModuleCrossfire(uint8_t idx) @@ -86,24 +91,28 @@ inline bool isExtraModule(uint8_t) #if defined(TARANIS_INTERNAL_PPM) inline bool isModulePPM(uint8_t idx) { - return idx == TRAINER_MODULE || - (idx == INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || - (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM)); + return (idx == INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || + (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM); } #else inline bool isModulePPM(uint8_t idx) { - return idx == TRAINER_MODULE || - isExtraModule(idx) || + return isExtraModule(idx) || (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM); } #endif inline bool isModuleR9M(uint8_t idx) { - return g_model.moduleData[idx].type == MODULE_TYPE_R9M; + return g_model.moduleData[idx].type == MODULE_TYPE_R9M || g_model.moduleData[idx].type == MODULE_TYPE_R9M_LITE; } +inline bool isModuleR9M2(uint8_t idx) +{ + return g_model.moduleData[idx].type == MODULE_TYPE_R9M2 || g_model.moduleData[idx].type == MODULE_TYPE_R9M_LITE2 || g_model.moduleData[idx].type == MODULE_TYPE_R9M_LITE_PRO2; +} + +#if defined(PCBXLITE) inline bool isModuleR9M_FCC(uint8_t idx) { return isModuleR9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_FCC; @@ -128,13 +137,43 @@ inline bool isModuleR9M_AU_PLUS(uint8_t idx) { return isModuleR9M(idx) && g_model.moduleData[idx].subType != MODULE_SUBTYPE_R9M_AUPLUS; } +#else +inline bool isModuleR9M_FCC(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FCC; +} +inline bool isModuleR9M_LBT(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_EU; +} + +inline bool isModuleR9M_FCC_VARIANT(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region != MODULE_R9M_REGION_EU; +} + +inline bool isModuleR9M_EUPLUS(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FLEX && g_model.moduleData[idx].r9m.freq == MODULE_R9M_FREQ_868MHZ; +} + +inline bool isModuleR9M_AU_PLUS(uint8_t idx) +{ + return isModuleR9M(idx) && g_model.moduleData[idx].r9m.region == MODULE_R9M_REGION_FLEX && g_model.moduleData[idx].r9m.freq == MODULE_R9M_FREQ_915MHZ; +} +#endif inline bool isModulePXX(uint8_t idx) { return isModuleXJT(idx) || isModuleR9M(idx); } +inline bool isModulePXX2(uint8_t idx) +{ + return isModuleXJT2(idx) || isModuleR9M2(idx); +} + #if defined(DSM2) inline bool isModuleDSM2(uint8_t idx) { @@ -152,8 +191,8 @@ inline bool isModuleDSM2(uint8_t idx) } #endif -// order is the same as in enum Protocols in myeeprom.h (none, ppm, pxx, dsm, crossfire, multi, r9m, sbus) -static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4, 8, 8}; // relative to 8! +// order is the same as in enum Protocols in myeeprom.h (none, ppm, pxx, pxx2, dsm, crossfire, multi, r9m, r9m2, sbus) +static const int8_t maxChannelsModules[] = { 0, 8, 8, 16, -2, 8, 4, 8, 16, 8}; // relative to 8! static const int8_t maxChannelsXJT[] = { 0, 8, 0, 4 }; // relative to 8! constexpr int8_t MAX_TRAINER_CHANNELS_M8 = MAX_TRAINER_CHANNELS - 8; @@ -163,27 +202,12 @@ inline int8_t maxModuleChannels_M8(uint8_t idx) { if (isExtraModule(idx)) return MAX_EXTRA_MODULE_CHANNELS_M8; - else if (idx == TRAINER_MODULE) - return MAX_TRAINER_CHANNELS_M8; else if (isModuleXJT(idx)) return maxChannelsXJT[1 + g_model.moduleData[idx].rfProtocol]; else return maxChannelsModules[g_model.moduleData[idx].type]; } -inline int8_t maxModuleChannels(uint8_t idx) -{ - return 8 + maxModuleChannels_M8(idx); -} - -inline int8_t minModuleChannels(uint8_t idx) -{ - if (isModuleCrossfire(idx)) - return 16; - else - return 1; -} - inline int8_t defaultModuleChannels_M8(uint8_t idx) { if (isModulePPM(idx)) @@ -192,6 +216,8 @@ inline int8_t defaultModuleChannels_M8(uint8_t idx) return 0; // 8 channels else if (isModuleMultimoduleDSM2(idx)) return -1; // 7 channels + else if (isModulePXX2(idx)) + return 8; // 16 channels else return maxModuleChannels_M8(idx); } diff --git a/radio/src/pulses/multi_arm.cpp b/radio/src/pulses/multi.cpp similarity index 87% rename from radio/src/pulses/multi_arm.cpp rename to radio/src/pulses/multi.cpp index cb15c1e01..4465a9c08 100644 --- a/radio/src/pulses/multi_arm.cpp +++ b/radio/src/pulses/multi.cpp @@ -57,7 +57,7 @@ static void sendFailsafeChannels(uint8_t port) uint8_t bitsavailable = 0; for (int i = 0; i < MULTI_CHANS; i++) { - int16_t failsafeValue = g_model.moduleData[port].failsafeChannels[i]; + int16_t failsafeValue = g_model.failsafeChannels[i]; int pulseValue; if (g_model.moduleData[port].failsafeMode == FAILSAFE_HOLD) failsafeValue = FAILSAFE_CHANNEL_HOLD; @@ -86,31 +86,31 @@ static void sendFailsafeChannels(uint8_t port) } } -void setupPulsesMultimodule(uint8_t port) +void setupPulsesMultimodule() { static int counter = 0; #if defined(PPM_PIN_SERIAL) - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; + extmodulePulsesData.dsm2.serialByte = 0 ; + extmodulePulsesData.dsm2.serialBitCount = 0 ; #else - modulePulsesData[EXTERNAL_MODULE].dsm2.rest = multiSyncStatus.getAdjustedRefreshRate(); - modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; + extmodulePulsesData.dsm2.rest = multiSyncStatus.getAdjustedRefreshRate(); + extmodulePulsesData.dsm2.index = 0; #endif - modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + 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[port].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[port].failsafeMode != FAILSAFE_RECEIVER) { - sendFrameProtocolHeader(port, true); - sendFailsafeChannels(port); + } 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(port, false); - sendChannels(port); + sendFrameProtocolHeader(EXTERNAL_MODULE, false); + sendChannels(EXTERNAL_MODULE); } putDsm2Flush(); @@ -152,16 +152,16 @@ void sendFrameProtocolHeader(uint8_t port, bool failsafe) int8_t optionValue = g_model.moduleData[port].multi.optionValue; uint8_t protoByte = 0; - if (moduleFlag[port] == MODULE_BIND) + if (moduleSettings[port].mode == MODULE_MODE_BIND) protoByte |= MULTI_SEND_BIND; - else if (moduleFlag[port] == MODULE_RANGECHECK) + else if (moduleSettings[port].mode == MODULE_MODE_RANGECHECK) protoByte |= MULTI_SEND_RANGECHECK; // rfProtocol if (g_model.moduleData[port].getMultiProtocol(true) == MM_RF_PROTO_DSM2) { // Autobinding should always be done in DSMX 11ms - if (g_model.moduleData[port].multi.autoBindMode && moduleFlag[port] == MODULE_BIND) + if (g_model.moduleData[port].multi.autoBindMode && moduleSettings[port].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 diff --git a/radio/src/pulses/ppm_arm.cpp b/radio/src/pulses/ppm.cpp similarity index 61% rename from radio/src/pulses/ppm_arm.cpp rename to radio/src/pulses/ppm.cpp index 04b8f50c7..561f4ba03 100644 --- a/radio/src/pulses/ppm_arm.cpp +++ b/radio/src/pulses/ppm.cpp @@ -21,7 +21,7 @@ #include "opentx.h" template -void setupPulsesPPM(uint8_t port, PpmPulsesData * ppmPulsesData) +void setupPulsesPPM(PpmPulsesData * ppmPulsesData, uint8_t channelsStart, int8_t channelsCount, int8_t frameLength) { int16_t PPM_range = g_model.extendedLimits ? (512*LIMIT_EXT_PERCENT/100) * 2 : 512 * 2; // range of 0.7 .. 1.7msec @@ -29,8 +29,8 @@ void setupPulsesPPM(uint8_t port, PpmPulsesData * ppmPulsesData) // each pulse is 0.7..1.7ms long with a 0.3ms stop tail // The pulse ISR is 2mhz that's why everything is multiplied by 2 - uint32_t firstCh = g_model.moduleData[port].channelsStart; - uint32_t lastCh = min(MAX_OUTPUT_CHANNELS, firstCh + 8 + g_model.moduleData[port].channelsCount); + uint8_t firstCh = channelsStart; + uint8_t lastCh = min(MAX_OUTPUT_CHANNELS, firstCh + 8 + channelsCount); #if defined(STM32) ppmPulsesData->ptr = ppmPulsesData->pulses; @@ -40,7 +40,7 @@ void setupPulsesPPM(uint8_t port, PpmPulsesData * ppmPulsesData) #endif int32_t rest = 22500u * 2; - rest += (int32_t(g_model.moduleData[port].ppm.frameLength)) * 1000; + rest += int32_t(frameLength) * 1000; for (uint32_t i=firstCh; i * ppmPulsesData) rest = limit(9000, rest, 65535); /* avoids that CCR2 is bigger than ARR which would cause reboot */ #if defined(STM32) *ppmPulsesData->ptr++ = rest; + *ppmPulsesData->ptr = 0; // it's needed in case PPM is sent without DMA (we stop when we reach this 0) #else *ptr = rest; *(ptr + 1) = 0; #endif } -void setupPulsesPPMModule(uint8_t port) -{ - setupPulsesPPM(port, &modulePulsesData[port].ppm); -} - void setupPulsesPPMTrainer() { - setupPulsesPPM(TRAINER_MODULE, &trainerPulsesData.ppm); + setupPulsesPPM(&trainerPulsesData.ppm, g_model.trainerData.channelsStart, g_model.trainerData.channelsCount, g_model.trainerData.frameLength); } + +#if defined(PCBTARANIS) && defined(TARANIS_INTERNAL_PPM) +void setupPulsesPPMInternalModule() +{ + setupPulsesPPM(&intmodulePulsesData.ppm, g_model.moduleData[INTERNAL_MODULE].channelsStart, g_model.moduleData[INTERNAL_MODULE].channelsCount, g_model.moduleData[INTERNAL_MODULE].ppm.frameLength); +} +#endif + +void setupPulsesPPMExternalModule() +{ + setupPulsesPPM(&extmodulePulsesData.ppm, g_model.moduleData[EXTERNAL_MODULE].channelsStart, g_model.moduleData[EXTERNAL_MODULE].channelsCount, g_model.moduleData[EXTERNAL_MODULE].ppm.frameLength); +} + + diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp new file mode 100755 index 000000000..c0679b01b --- /dev/null +++ b/radio/src/pulses/pulses.cpp @@ -0,0 +1,382 @@ +/* + * 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. + */ + +#include "opentx.h" +#include "io/frsky_pxx2.h" +#include "pulses/pxx2.h" + +uint8_t s_pulses_paused = 0; +ModuleSettings moduleSettings[NUM_MODULES]; +InternalModulePulsesData intmodulePulsesData __DMA; +ExternalModulePulsesData extmodulePulsesData __DMA; +TrainerPulsesData trainerPulsesData __DMA; + +uint8_t getModuleType(uint8_t module) +{ + uint8_t type = g_model.moduleData[module].type; + +#if defined(HARDWARE_INTERNAL_MODULE) + if (module == INTERNAL_MODULE && isInternalModuleAvailable(type)) { + return type; + } +#endif + + if (module == EXTERNAL_MODULE && isExternalModuleAvailable(type)) { + return type; + } + + return MODULE_TYPE_NONE; +} + +uint8_t getRequiredProtocol(uint8_t module) +{ + uint8_t protocol; + + switch (getModuleType(module)) { + case MODULE_TYPE_PPM: + protocol = PROTOCOL_CHANNELS_PPM; + break; + + case MODULE_TYPE_XJT: +#if defined(INTMODULE_USART) + if (module == INTERNAL_MODULE) { + protocol = PROTOCOL_CHANNELS_PXX1_SERIAL; + break; + } +#endif + // no break + + case MODULE_TYPE_R9M: + protocol = PROTOCOL_CHANNELS_PXX1_PULSES; + break; + + case MODULE_TYPE_R9M_LITE: + protocol = PROTOCOL_CHANNELS_PXX1_SERIAL; + break; + + case MODULE_TYPE_XJT2: + case MODULE_TYPE_R9M2: + case MODULE_TYPE_R9M_LITE2: + case MODULE_TYPE_R9M_LITE_PRO2: + protocol = PROTOCOL_CHANNELS_PXX2; + break; + + case MODULE_TYPE_SBUS: + protocol = PROTOCOL_CHANNELS_SBUS; + break; + +#if defined(MULTIMODULE) + case MODULE_TYPE_MULTIMODULE: + protocol = PROTOCOL_CHANNELS_MULTIMODULE; + break; +#endif + +#if defined(DSM2) + case MODULE_TYPE_DSM2: + protocol = limit(PROTOCOL_CHANNELS_DSM2_LP45, PROTOCOL_CHANNELS_DSM2_LP45+g_model.moduleData[module].rfProtocol, PROTOCOL_CHANNELS_DSM2_DSMX); + // The module is set to OFF during one second before BIND start + { + static tmr10ms_t bindStartTime = 0; + if (moduleSettings[module].mode == MODULE_MODE_BIND) { + if (bindStartTime == 0) bindStartTime = get_tmr10ms(); + if ((tmr10ms_t)(get_tmr10ms() - bindStartTime) < 100) { + protocol = PROTOCOL_CHANNELS_NONE; + break; + } + } + else { + bindStartTime = 0; + } + } + break; +#endif + +#if defined(CROSSFIRE) + case MODULE_TYPE_CROSSFIRE: + protocol = PROTOCOL_CHANNELS_CROSSFIRE; + break; +#endif + + default: + protocol = PROTOCOL_CHANNELS_NONE; + break; + } + + if (s_pulses_paused) { + protocol = PROTOCOL_CHANNELS_NONE; + } + +#if 0 + // will need an EEPROM conversion + if (moduleSettings[module].mode == MODULE_OFF) { + protocol = PROTOCOL_CHANNELS_NONE; + } +#endif + + return protocol; +} + +void disablePulses(uint8_t module, uint8_t protocol) +{ + // stop existing protocol hardware + + switch (protocol) { +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_PULSES: + disable_pxx1_pulses(module); + break; + +#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + disable_pxx1_serial(module); + break; +#endif +#endif + +#if defined(DSM2) + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: + disable_serial(module); + break; +#endif + +#if defined(CROSSFIRE) + case PROTOCOL_CHANNELS_CROSSFIRE: + // TODO disable_module_timer(module); + break; +#endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + disable_pxx2(module); + break; +#endif + +#if defined(MULTIMODULE) + case PROTOCOL_CHANNELS_MULTIMODULE: +#endif + case PROTOCOL_CHANNELS_SBUS: + disable_serial(module); + break; + + case PROTOCOL_CHANNELS_PPM: + disable_ppm(module); + break; + } +} + +void enablePulses(uint8_t module, uint8_t protocol) +{ + // start new protocol hardware here + + switch (protocol) { +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_PULSES: + init_pxx1_pulses(module); + break; + +#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + init_pxx1_serial(module); + break; +#endif +#endif + +#if defined(DSM2) + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: + init_serial(module, DSM2_BAUDRATE, DSM2_PERIOD * 2000); + break; +#endif + +#if defined(CROSSFIRE) + case PROTOCOL_CHANNELS_CROSSFIRE: + // TODO init_module_timer(module, CROSSFIRE_PERIOD, true); + break; +#endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + init_pxx2(module); + break; +#endif + +#if defined(MULTIMODULE) + case PROTOCOL_CHANNELS_MULTIMODULE: + init_serial(module, MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000); + break; +#endif + + case PROTOCOL_CHANNELS_SBUS: + init_serial(module, SBUS_BAUDRATE, SBUS_PERIOD_HALF_US); + break; + + case PROTOCOL_CHANNELS_PPM: + init_ppm(module); + break; + } +} + +void 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_PXX_PERIOD); + break; +#endif + +#if defined(PXX1) && defined(INTMODULE_USART) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + intmodulePulsesData.pxx_uart.setupFrame(INTERNAL_MODULE); + scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX_PERIOD); + break; +#endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE); + scheduleNextMixerCalculation(INTERNAL_MODULE, moduleSettings[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleSettings[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER ? 1 : PXX2_PERIOD); + break; +#endif + +#if defined(PCBTARANIS) && defined(TARANIS_INTERNAL_PPM) + case PROTOCOL_CHANNELS_PPM: + setupPulsesPPM(&extmodulePulsesData.ppm, g_model.moduleData[INTERNAL_MODULE].channelsStart, g_model.moduleData[INTERNAL_MODULE].channelsCount, g_model.moduleData[INTERNAL_MODULE].ppm.frameLength); + scheduleNextMixerCalculation(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE)); + break; +#endif + + default: + break; + } +} + +void setupPulsesExternalModule(uint8_t protocol) +{ + switch (protocol) { +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_PULSES: + extmodulePulsesData.pxx.setupFrame(EXTERNAL_MODULE); + scheduleNextMixerCalculation(EXTERNAL_MODULE, PXX_PULSES_PERIOD); + break; +#endif + +#if defined(PXX1) && defined(EXTMODULE_USART) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + extmodulePulsesData.pxx_uart.setupFrame(EXTERNAL_MODULE); + scheduleNextMixerCalculation(EXTERNAL_MODULE, EXTMODULE_PXX_SERIAL_PERIOD); + break; +#endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + extmodulePulsesData.pxx2.setupFrame(EXTERNAL_MODULE); + scheduleNextMixerCalculation(EXTERNAL_MODULE, PXX2_PERIOD); + break; +#endif + + case PROTOCOL_CHANNELS_SBUS: + setupPulsesSbus(); + scheduleNextMixerCalculation(EXTERNAL_MODULE, SBUS_PERIOD); + break; + +#if defined(DSM2) + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: + setupPulsesDSM2(); + scheduleNextMixerCalculation(EXTERNAL_MODULE, DSM2_PERIOD); + break; +#endif + +#if defined(CROSSFIRE) + case PROTOCOL_CHANNELS_CROSSFIRE: + setupPulsesCrossfire(); + scheduleNextMixerCalculation(EXTERNAL_MODULE, CROSSFIRE_PERIOD); + break; +#endif + +#if defined(MULTIMODULE) + case PROTOCOL_CHANNELS_MULTIMODULE: + setupPulsesMultimodule(); + scheduleNextMixerCalculation(EXTERNAL_MODULE, MULTIMODULE_PERIOD); + break; +#endif + + case PROTOCOL_CHANNELS_PPM: + setupPulsesPPMExternalModule(); + scheduleNextMixerCalculation(EXTERNAL_MODULE, PPM_PERIOD(EXTERNAL_MODULE)); + break; + + default: + break; + } +} + +void setupPulses(uint8_t module, uint8_t protocol) +{ + switch (module) { +#if defined(HARDWARE_INTERNAL_MODULE) + case INTERNAL_MODULE: + setupPulsesInternalModule(protocol); + break; +#endif + + case EXTERNAL_MODULE: + setupPulsesExternalModule(protocol); + break; + } +} + +bool setupPulses(uint8_t module) +{ + uint8_t protocol = getRequiredProtocol(module); + + heartbeat |= (HEART_TIMER_PULSES << module); + + if (moduleSettings[module].protocol != protocol) { + disablePulses(module, moduleSettings[module].protocol); + moduleSettings[module].protocol = protocol; + enablePulses(module, protocol); + return false; + } + else { + setupPulses(module, protocol); + return true; + } +} + +void setCustomFailsafe(uint8_t moduleIndex) +{ + if (moduleIndex < NUM_MODULES) { + for (int ch=0; ch= sentModuleChannels(moduleIndex) + g_model.moduleData[moduleIndex].channelsStart) { + g_model.failsafeChannels[ch] = 0; + } + else if (g_model.failsafeChannels[ch] < FAILSAFE_CHANNEL_HOLD) { + g_model.failsafeChannels[ch] = channelOutputs[ch]; + } + } + } +} diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 6a0739149..405956259 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -21,37 +21,25 @@ #ifndef _PULSES_H_ #define _PULSES_H_ -enum ModuleFlag -{ - MODULE_NORMAL_MODE, - MODULE_RANGECHECK, - MODULE_BIND, - // MODULE_OFF, // will need an EEPROM conversion -}; - - extern uint8_t moduleFlag[NUM_MODULES]; +#include "definitions.h" +#include "dataconstants.h" +#include "pulses_common.h" +#include "pulses/pxx1.h" +#include "pulses/pxx2.h" #if NUM_MODULES > 1 - #define IS_RANGECHECK_ENABLE() (moduleFlag[0] == MODULE_RANGECHECK || moduleFlag[1] == MODULE_RANGECHECK) + #define IS_RANGECHECK_ENABLE() (moduleSettings[0].mode == MODULE_MODE_RANGECHECK || moduleSettings[1].mode == MODULE_MODE_RANGECHECK) #else - #define IS_RANGECHECK_ENABLE() (moduleFlag[0] == MODULE_RANGECHECK) + #define IS_RANGECHECK_ENABLE() (moduleSettings[0].mode == MODULE_MODE_RANGECHECK) #endif -#if defined(DSM2) && !defined(PCBTARANIS) +#if defined(PCBSKY9X) && defined(DSM2) #define DSM2_BIND_TIMEOUT 255 // 255*11ms extern uint8_t dsm2BindTimer; #endif - #define IS_PPM_PROTOCOL(protocol) (protocol==PROTO_PPM) - -#if defined(PXX) - #define IS_PXX_PROTOCOL(protocol) (protocol==PROTO_PXX) -#else - #define IS_PXX_PROTOCOL(protocol) (0) -#endif - #if defined(DSM2) - #define IS_DSM2_PROTOCOL(protocol) (protocol>=PROTO_DSM2_LP45 && protocol<=PROTO_DSM2_DSMX) + #define IS_DSM2_PROTOCOL(protocol) (protocol>=PROTOCOL_CHANNELS_DSM2_LP45 && protocol<=PROTOCOL_CHANNELS_DSM2_DSMX) #else #define IS_DSM2_PROTOCOL(protocol) (0) #endif @@ -63,7 +51,7 @@ enum ModuleFlag #endif #if defined(MULTIMODULE) - #define IS_MULTIMODULE_PROTOCOL(protocol) (protocol==PROTO_MULTIMODULE) + #define IS_MULTIMODULE_PROTOCOL(protocol) (protocol==PROTOCOL_CHANNELS_MULTIMODULE) #if !defined(DSM2) #error You need to enable DSM2 = PPM for MULTIMODULE support #endif @@ -71,9 +59,258 @@ enum ModuleFlag #define IS_MULTIMODULE_PROTOCOL(protocol) (0) #endif - #define IS_SBUS_PROTOCOL(protocol) (protocol == PROTO_SBUS) +#define IS_SBUS_PROTOCOL(protocol) (protocol == PROTOCOL_CHANNELS_SBUS) + +extern uint8_t s_pulses_paused; + +enum ModuleSettingsMode +{ + MODULE_MODE_NORMAL, + MODULE_MODE_SPECTRUM_ANALYSER, + MODULE_MODE_POWER_METER, + MODULE_MODE_GET_HARDWARE_INFO, + MODULE_MODE_MODULE_SETTINGS, + MODULE_MODE_RECEIVER_SETTINGS, + MODULE_MODE_BEEP_FIRST, + MODULE_MODE_REGISTER = MODULE_MODE_BEEP_FIRST, + MODULE_MODE_BIND, + MODULE_MODE_SHARE, + MODULE_MODE_RANGECHECK, +}; + +PACK(struct ModuleSettings { + uint8_t protocol:4; + uint8_t mode:4; + uint8_t paused:1; + uint8_t spare:7; + uint16_t counter; +}); + +extern ModuleSettings moduleSettings[NUM_MODULES]; + +template struct PpmPulsesData { + T pulses[20]; + T * ptr; +}; + +#if defined(PPM_PIN_SERIAL) +PACK(struct Dsm2SerialPulsesData { + uint8_t pulses[64]; + uint8_t * ptr; + uint8_t serialByte ; + uint8_t serialBitCount; + uint16_t _alignment; +}); +typedef Dsm2SerialPulsesData Dsm2PulsesData; +#else +#define MAX_PULSES_TRANSITIONS 300 +PACK(struct Dsm2TimerPulsesData { + pulse_duration_t pulses[MAX_PULSES_TRANSITIONS]; + pulse_duration_t * ptr; + uint16_t rest; + uint8_t index; +}); +typedef Dsm2TimerPulsesData Dsm2PulsesData; +#endif + +#define PPM_PERIOD_HALF_US(module) ((g_model.moduleData[module].ppm.frameLength * 5 + 225) * 200) /*half us*/ +#define PPM_PERIOD(module) (PPM_PERIOD_HALF_US(module) / 2000) /*ms*/ +#define DSM2_BAUDRATE 125000 +#define DSM2_PERIOD 22 /*ms*/ +#define SBUS_BAUDRATE 100000 +#define SBUS_PERIOD_HALF_US ((g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225) * 200) /*half us*/ +#define SBUS_PERIOD (SBUS_PERIOD_HALF_US / 2000) /*ms*/ +#define MULTIMODULE_BAUDRATE 100000 +#define MULTIMODULE_PERIOD 7 /*ms*/ + +#define CROSSFIRE_FRAME_MAXLEN 64 +PACK(struct CrossfirePulsesData { + uint8_t pulses[CROSSFIRE_FRAME_MAXLEN]; + uint8_t length; +}); + +union InternalModulePulsesData { +#if defined(PXX1) + #if defined(INTMODULE_USART) + UartPxx1Pulses pxx_uart; + #else + PwmPxx1Pulses pxx; + #endif +#endif + +#if defined(PXX2) + Pxx2Pulses pxx2; +#endif + +#if defined(TARANIS_INTERNAL_PPM) + PpmPulsesData ppm; +#endif +} __ALIGNED(4); + +union ExternalModulePulsesData { +#if defined(PXX1) + #if defined(EXTMODULE_USART) + UartPxx1Pulses pxx_uart; + #endif + #if defined(PPM_PIN_SERIAL) + SerialPxx1Pulses pxx; + #else + PwmPxx1Pulses pxx; + #endif +#endif + +#if defined(PXX2) + Pxx2Pulses pxx2; +#endif + +#if defined(DSM2) || defined(MULTIMODULE) || defined(SBUS) + Dsm2PulsesData dsm2; +#endif + + PpmPulsesData ppm; + + CrossfirePulsesData crossfire; +} __ALIGNED(4); + +/* The __ALIGNED keyword is required to align the struct inside the modulePulsesData below, + * which is also defined to be __DMA (which includes __ALIGNED) aligned. + * Arrays in C/C++ are always defined to be *contiguously*. The first byte of the second element is therefore always + * sizeof(ModulePulsesData). __ALIGNED is required for sizeof(ModulePulsesData) to be a multiple of the alignment. + */ - #include "pulses_arm.h" +extern InternalModulePulsesData intmodulePulsesData; +extern ExternalModulePulsesData extmodulePulsesData; + +union TrainerPulsesData { + PpmPulsesData ppm; +}; + +extern TrainerPulsesData trainerPulsesData; + +bool setupPulses(uint8_t module); +void setupPulsesDSM2(); +void setupPulsesCrossfire(); +void setupPulsesMultimodule(); +void setupPulsesSbus(); +void setupPulsesPPMInternalModule(); +void setupPulsesPPMExternalModule(); +void setupPulsesPPMTrainer(); +void sendByteDsm2(uint8_t b); +void putDsm2Flush(); +void putDsm2SerialBit(uint8_t bit); +void sendByteSbus(uint8_t b); + +#if defined(HUBSAN) +void Hubsan_Init(); +#endif + +inline void startPulses() +{ + s_pulses_paused = false; + +#if defined(PCBTARANIS) || defined(PCBHORUS) + setupPulses(INTERNAL_MODULE); + setupPulses(EXTERNAL_MODULE); +#else + setupPulses(EXTERNAL_MODULE); +#endif + +#if defined(HUBSAN) + Hubsan_Init(); +#endif +} + +enum ChannelsProtocols { + PROTOCOL_CHANNELS_UNINITIALIZED, + PROTOCOL_CHANNELS_NONE, + PROTOCOL_CHANNELS_PPM, +#if defined(PXX) || defined(DSM2) + PROTOCOL_CHANNELS_PXX1_PULSES, + PROTOCOL_CHANNELS_PXX1_SERIAL, +#endif +#if defined(DSM2) + PROTOCOL_CHANNELS_DSM2_LP45, + PROTOCOL_CHANNELS_DSM2_DSM2, + PROTOCOL_CHANNELS_DSM2_DSMX, +#endif + PROTOCOL_CHANNELS_CROSSFIRE, + PROTOCOL_CHANNELS_MULTIMODULE, + PROTOCOL_CHANNELS_SBUS, + PROTOCOL_CHANNELS_PXX2 +}; + +inline bool pulsesStarted() { return moduleSettings[0].protocol != PROTOCOL_CHANNELS_UNINITIALIZED; } +inline void pausePulses() { s_pulses_paused = true; } +inline void resumePulses() { s_pulses_paused = false; } + +#define SEND_FAILSAFE_NOW(idx) moduleSettings[idx].counter = 1 + +inline void SEND_FAILSAFE_1S() +{ + for (int i=0; i(PROTO_DSM2_LP45, PROTO_DSM2_LP45+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, PROTO_DSM2_DSMX); - // The module is set to OFF during one second before BIND start - { - static tmr10ms_t bindStartTime = 0; - if (moduleFlag[EXTERNAL_MODULE] == MODULE_BIND) { - if (bindStartTime == 0) bindStartTime = get_tmr10ms(); - if ((tmr10ms_t)(get_tmr10ms() - bindStartTime) < 100) { - required_protocol = PROTO_NONE; - break; - } - } - else { - bindStartTime = 0; - } - } - break; -#endif -#if defined(CROSSFIRE) - case MODULE_TYPE_CROSSFIRE: - required_protocol = PROTO_CROSSFIRE; - break; -#endif - default: - required_protocol = PROTO_NONE; - break; - } - break; - } - - if (s_pulses_paused) { - required_protocol = PROTO_NONE; - } - -#if 0 - // will need an EEPROM conversion - if (moduleFlag[port] == MODULE_OFF) { - required_protocol = PROTO_NONE; - } -#endif - - return required_protocol; -} - -void setupPulsesPXX(uint8_t port) -{ -#if defined(INTMODULE_USART) && defined(EXTMODULE_USART) - modulePulsesData[port].pxx_uart.setupFrame(port); -#elif !defined(INTMODULE_USART) && !defined(EXTMODULE_USART) - modulePulsesData[port].pxx.setupFrame(port); -#else - if (IS_UART_MODULE(port)) - modulePulsesData[port].pxx_uart.setupFrame(port); - else - modulePulsesData[port].pxx.setupFrame(port); -#endif -} - -void setupPulses(uint8_t port) -{ - bool init_needed = false; - uint8_t required_protocol = getRequiredProtocol(port); - - heartbeat |= (HEART_TIMER_PULSES << port); - - if (s_current_protocol[port] != required_protocol) { - init_needed = true; - switch (s_current_protocol[port]) { // stop existing protocol hardware - case PROTO_PXX: - disable_pxx(port); - break; - -#if defined(DSM2) - case PROTO_DSM2_LP45: - case PROTO_DSM2_DSM2: - case PROTO_DSM2_DSMX: - disable_serial(port); - break; -#endif - -#if defined(CROSSFIRE) - case PROTO_CROSSFIRE: - disable_module_timer(port); - break; -#endif - -#if defined(PXX2) - case PROTO_PXX2: - disable_module_timer(port); - break; -#endif - -#if defined(MULTIMODULE) - case PROTO_MULTIMODULE: -#endif - case PROTO_SBUS: - disable_serial(port); - break; - - case PROTO_PPM: - disable_ppm(port); - break; - - default: - disable_no_pulses(port); - break; - } - s_current_protocol[port] = required_protocol; - } - - // Set up output data here - switch (required_protocol) { - case PROTO_PXX: - setupPulsesPXX(port); - scheduleNextMixerCalculation(port, PXX_PERIOD); - break; - - case PROTO_SBUS: - setupPulsesSbus(port); - scheduleNextMixerCalculation(port, SBUS_PERIOD); - break; - -#if defined(DSM2) - case PROTO_DSM2_LP45: - case PROTO_DSM2_DSM2: - case PROTO_DSM2_DSMX: - setupPulsesDSM2(port); - scheduleNextMixerCalculation(port, DSM2_PERIOD); - break; -#endif - -#if defined(CROSSFIRE) - case PROTO_CROSSFIRE: - if (telemetryProtocol == PROTOCOL_PULSES_CROSSFIRE && !init_needed) { - uint8_t * crossfire = modulePulsesData[port].crossfire.pulses; - uint8_t len; -#if defined(LUA) - if (outputTelemetryBufferTrigger != 0x00 && outputTelemetryBufferSize > 0) { - memcpy(crossfire, outputTelemetryBuffer, outputTelemetryBufferSize); - len = outputTelemetryBufferSize; - outputTelemetryBufferTrigger = 0x00; - outputTelemetryBufferSize = 0; - } - else -#endif - { - len = createCrossfireChannelsFrame(crossfire, &channelOutputs[g_model.moduleData[port].channelsStart]); - } - sportSendBuffer(crossfire, len); - } - scheduleNextMixerCalculation(port, CROSSFIRE_PERIOD); - break; -#endif - -#if defined(PXX2) - case PROTO_PXX2: - if (telemetryProtocol == PROTOCOL_FRSKY_SPORT && !init_needed) { - modulePulsesData[port].pxx2.setupFrame(port); - sportSendBuffer(modulePulsesData[port].pxx2.getData(), modulePulsesData[port].pxx2.getSize()); - } - scheduleNextMixerCalculation(port, PXX2_PERIOD); - break; -#endif - -#if defined(MULTIMODULE) - case PROTO_MULTIMODULE: - setupPulsesMultimodule(port); - scheduleNextMixerCalculation(port, MULTIMODULE_PERIOD); - break; -#endif - - case PROTO_PPM: -#if defined(PCBSKY9X) - case PROTO_NONE: -#endif - setupPulsesPPMModule(port); - scheduleNextMixerCalculation(port, PPM_PERIOD(port)); - break; - - default: - break; - } - - if (init_needed) { - switch (required_protocol) { // Start new protocol hardware here - case PROTO_PXX: - init_pxx(port); - break; - -#if defined(DSM2) - case PROTO_DSM2_LP45: - case PROTO_DSM2_DSM2: - case PROTO_DSM2_DSMX: - init_serial(port, DSM2_BAUDRATE, DSM2_PERIOD * 2000); - break; -#endif - -#if defined(CROSSFIRE) - case PROTO_CROSSFIRE: - init_module_timer(port, CROSSFIRE_PERIOD, true); - break; -#endif - -#if defined(PXX2) - case PROTO_PXX2: - init_module_timer(port, PXX2_PERIOD, true); - break; -#endif - -#if defined(MULTIMODULE) - case PROTO_MULTIMODULE: - init_serial(port, MULTIMODULE_BAUDRATE, MULTIMODULE_PERIOD * 2000); - break; -#endif - - case PROTO_SBUS: - init_serial(port, SBUS_BAUDRATE, SBUS_PERIOD_HALF_US); - break; - - case PROTO_PPM: - init_ppm(port); - break; - - default: - init_no_pulses(port); - break; - } - } -} - -void setCustomFailsafe(uint8_t moduleIndex) -{ - if (moduleIndex < NUM_MODULES) { - for (int ch=0; ch= sentModuleChannels(moduleIndex) + g_model.moduleData[moduleIndex].channelsStart) { - g_model.moduleData[moduleIndex].failsafeChannels[ch] = 0; - } - else if (g_model.moduleData[moduleIndex].failsafeChannels[ch] < FAILSAFE_CHANNEL_HOLD) { - g_model.moduleData[moduleIndex].failsafeChannels[ch] = channelOutputs[ch]; - } - } - } -} diff --git a/radio/src/pulses/pulses_arm.h b/radio/src/pulses/pulses_arm.h deleted file mode 100644 index fb512de85..000000000 --- a/radio/src/pulses/pulses_arm.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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 _PULSES_ARM_H_ -#define _PULSES_ARM_H_ - -#include "pulses/pxx2.h" -#include "pulses/pxx1.h" - -#if NUM_MODULES == 2 - #define MODULES_INIT(...) __VA_ARGS__, __VA_ARGS__ -#else - #define MODULES_INIT(...) __VA_ARGS__ -#endif - -extern uint8_t s_current_protocol[NUM_MODULES]; -extern uint8_t s_pulses_paused; -extern uint16_t failsafeCounter[NUM_MODULES]; - -template struct PpmPulsesData { - T pulses[20]; - T * ptr; -}; - -#if defined(PPM_PIN_SERIAL) -PACK(struct Dsm2SerialPulsesData { - uint8_t pulses[64]; - uint8_t * ptr; - uint8_t serialByte ; - uint8_t serialBitCount; - uint16_t _alignment; -}); -#else -#define MAX_PULSES_TRANSITIONS 300 -PACK(struct Dsm2TimerPulsesData { - pulse_duration_t pulses[MAX_PULSES_TRANSITIONS]; - pulse_duration_t * ptr; - uint16_t rest; - uint8_t index; -}); -#endif - -#define PPM_PERIOD_HALF_US(module) ((g_model.moduleData[module].ppm.frameLength * 5 + 225) * 200) /*half us*/ -#define PPM_PERIOD(module) (PPM_PERIOD_HALF_US(module) / 2000) /*ms*/ -#define DSM2_BAUDRATE 125000 -#define DSM2_PERIOD 22 /*ms*/ -#define SBUS_BAUDRATE 100000 -#define SBUS_PERIOD_HALF_US ((g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225) * 200) /*half us*/ -#define SBUS_PERIOD (SBUS_PERIOD_HALF_US / 2000) /*ms*/ -#define MULTIMODULE_BAUDRATE 100000 -#define MULTIMODULE_PERIOD 7 /*ms*/ - -#define CROSSFIRE_FRAME_MAXLEN 64 -PACK(struct CrossfirePulsesData { - uint8_t pulses[CROSSFIRE_FRAME_MAXLEN]; -}); - -union ModulePulsesData { -#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) - UartPxxPulses pxx_uart; -#endif -#if defined(PPM_PIN_SERIAL) - SerialPxxPulses pxx; -#elif !defined(INTMODULE_USART) || !defined(EXTMODULE_USART) - PwmPxxPulses pxx; -#endif - -#if defined(PXX2) - Pxx2Pulses pxx2; -#endif - -#if defined(PPM_PIN_SERIAL) - Dsm2SerialPulsesData dsm2; -#else - Dsm2TimerPulsesData dsm2; -#endif - - PpmPulsesData ppm; - CrossfirePulsesData crossfire; -} __ALIGNED(4); - -/* The __ALIGNED keyword is required to align the struct inside the modulePulsesData below, - * which is also defined to be __DMA (which includes __ALIGNED) aligned. - * Arrays in C/C++ are always defined to be *contiguously*. The first byte of the second element is therefore always - * sizeof(ModulePulsesData). __ALIGNED is required for sizeof(ModulePulsesData) to be a multiple of the alignment. - */ - -/* TODO: internal pulsedata only needs 200 bytes vs 300 bytes for external, both use 300 byte since we have a common struct */ -extern ModulePulsesData modulePulsesData[NUM_MODULES]; - -union TrainerPulsesData { - PpmPulsesData ppm; -}; - -extern TrainerPulsesData trainerPulsesData; -extern const uint16_t CRCTable[]; - -void setupPulses(uint8_t port); -void setupPulsesDSM2(uint8_t port); -void setupPulsesMultimodule(uint8_t port); -void setupPulsesSbus(uint8_t port); -void setupPulsesPXX(uint8_t port); -void setupPulsesPPMModule(uint8_t port); -void setupPulsesPPMTrainer(); -void sendByteDsm2(uint8_t b); -void putDsm2Flush(); -void putDsm2SerialBit(uint8_t bit); -void sendByteSbus(uint8_t byte); - -#if defined(HUBSAN) -void Hubsan_Init(); -#endif - -inline void startPulses() -{ - s_pulses_paused = false; - -#if defined(PCBTARANIS) || defined(PCBHORUS) - setupPulses(INTERNAL_MODULE); - setupPulses(EXTERNAL_MODULE); -#else - setupPulses(EXTERNAL_MODULE); -#endif - -#if defined(HUBSAN) - Hubsan_Init(); -#endif -} - -inline bool pulsesStarted() { return s_current_protocol[0] != 255; } -inline void pausePulses() { s_pulses_paused = true; } -inline void resumePulses() { s_pulses_paused = false; } - -#define SEND_FAILSAFE_NOW(idx) failsafeCounter[idx] = 1 - -inline void SEND_FAILSAFE_1S() -{ - for (int i=0; i -void PxxPulses::addChannels(uint8_t port, uint8_t sendFailsafe, uint8_t sendUpperChannels) -{ - uint16_t pulseValue = 0; - uint16_t pulseValueLow = 0; - - for (int8_t i=0; i<8; i++) { - if (sendFailsafe) { - if (g_model.moduleData[port].failsafeMode == FAILSAFE_HOLD) { - pulseValue = (i < sendUpperChannels ? 4095 : 2047); - } - else if (g_model.moduleData[port].failsafeMode == FAILSAFE_NOPULSES) { - pulseValue = (i < sendUpperChannels ? 2048 : 0); - } - else { - if (i < sendUpperChannels) { - int16_t failsafeValue = g_model.moduleData[port].failsafeChannels[8+i]; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - pulseValue = 4095; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - pulseValue = 2048; - } - else { - failsafeValue += 2*PPM_CH_CENTER(8+g_model.moduleData[port].channelsStart+i) - 2*PPM_CENTER; - pulseValue = limit(2049, (failsafeValue * 512 / 682) + 3072, 4094); - } - } - else { - int16_t failsafeValue = g_model.moduleData[port].failsafeChannels[i]; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - pulseValue = 2047; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - pulseValue = 0; - } - else { - failsafeValue += 2*PPM_CH_CENTER(g_model.moduleData[port].channelsStart+i) - 2*PPM_CENTER; - pulseValue = limit(1, (failsafeValue * 512 / 682) + 1024, 2046); - } - } - } - } - else { - if (i < sendUpperChannels) { - int channel = 8 + g_model.moduleData[port].channelsStart + i; - int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; - pulseValue = limit(2049, (value * 512 / 682) + 3072, 4094); - } - else if (i < sentModuleChannels(port)) { - int channel = g_model.moduleData[port].channelsStart + i; - int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; - pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); - } - else { - pulseValue = 1024; - } - } - - if (i & 1) { - PxxTransport::addByte(pulseValueLow); // Low byte of channel - PxxTransport::addByte(((pulseValueLow >> 8) & 0x0F) | (pulseValue << 4)); // 4 bits each from 2 channels - PxxTransport::addByte(pulseValue >> 4); // High byte of channel - } - else { - pulseValueLow = pulseValue; - } - } -} - -template -uint8_t PxxPulses::addFlag1(uint8_t port) -{ - uint8_t flag1 = (g_model.moduleData[port].rfProtocol << 6); - if (moduleFlag[port] == MODULE_BIND) { - flag1 |= (g_eeGeneral.countryCode << 1) | PXX_SEND_BIND; - } - else if (moduleFlag[port] == MODULE_RANGECHECK) { - flag1 |= PXX_SEND_RANGECHECK; - } - else if (g_model.moduleData[port].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[port].failsafeMode != FAILSAFE_RECEIVER) { - if (failsafeCounter[port]-- == 0) { - failsafeCounter[port] = 1000; - flag1 |= PXX_SEND_FAILSAFE; - } - if (failsafeCounter[port] == 0 && g_model.moduleData[port].channelsCount > 0) { - flag1 |= PXX_SEND_FAILSAFE; - } - } - PxxTransport::addByte(flag1); - return flag1; -} - -template -void PxxPulses::addExtraFlags(uint8_t port) -{ - // Ext. flag (holds antenna selection on Horus internal module, 0x00 otherwise) - uint8_t extra_flags = 0; - -#if defined(PCBHORUS) || defined(PCBXLITE) - if (port == INTERNAL_MODULE) { - extra_flags |= (g_model.moduleData[port].pxx.external_antenna << 0); - } -#endif - - extra_flags |= (g_model.moduleData[port].pxx.receiver_telem_off << 1); - extra_flags |= (g_model.moduleData[port].pxx.receiver_channel_9_16 << 2); - if (isModuleR9M(port)) { - extra_flags |= (min(g_model.moduleData[port].pxx.power, isModuleR9M_FCC_VARIANT(port) ? (uint8_t)R9M_FCC_POWER_MAX : (uint8_t)R9M_LBT_POWER_MAX) << 3); - if(isModuleR9M_EUPLUS(port)) - extra_flags |= (1 << 6); - } - - // Disable S.PORT if internal module is active - if (IS_TELEMETRY_INTERNAL_MODULE()) { - extra_flags |= (1 << 5); - } - PxxTransport::addByte(extra_flags); -} - -template class PxxPulses >; -template class PxxPulses >; -template class PxxPulses; -template class PxxPulses; diff --git a/radio/src/pulses/pxx.h b/radio/src/pulses/pxx.h index 31e7e16fc..e082e18f0 100644 --- a/radio/src/pulses/pxx.h +++ b/radio/src/pulses/pxx.h @@ -27,16 +27,24 @@ #define PXX_SEND_FAILSAFE (1 << 4) #define PXX_SEND_RANGECHECK (1 << 5) +#define PXX2_ON_SPORT_BAUDRATE 230400 +#define PXX2_PERIOD 4 // 4ms +#define PXX2_FRAME_MAXLENGTH 64 + +#define PXX_PULSES_PERIOD 9/*ms*/ +#define EXTMODULE_PXX_SERIAL_PERIOD 4/*ms*/ +#define EXTMODULE_PXX_SERIAL_BAUDRATE 420000 + #if defined(PXX_FREQUENCY_HIGH) - #define EXTMODULE_USART_PXX_BAUDRATE 420000 - #define INTMODULE_USART_PXX_BAUDRATE 450000 - #define PXX_PERIOD 4/*ms*/ + #define INTMODULE_PXX_BAUDRATE 450000 + #define INTMODULE_PXX_PERIOD 4/*ms*/ #else - #define EXTMODULE_USART_PXX_BAUDRATE 115200 - #define INTMODULE_USART_PXX_BAUDRATE 115200 - #define PXX_PERIOD 9/*ms*/ + #define INTMODULE_PXX_BAUDRATE 115200 + #define INTMODULE_PXX_PERIOD 9/*ms*/ #endif +#define EXTMODULE_USART_PXX2_BAUDRATE 230400 + #if defined(PXX_FREQUENCY_HIGH) && (!defined(INTMODULE_USART) || !defined(EXTMODULE_USART)) /* PXX uses 20 bytes (as of Rev 1.1 document) with 8 changes per byte + stop bit ~= 162 max pulses */ /* DSM2 uses 2 header + 12 channel bytes, with max 10 changes (8n2) per byte + 16 bits trailer ~= 156 max pulses */ @@ -47,32 +55,13 @@ #error "Pulses array needs to be increased (PXX_FREQUENCY=HIGH)" #endif - -#define PXX_PERIOD_HALF_US (PXX_PERIOD * 2000) - -class PxxCrcMixin { - protected: - void initCrc() - { - crc = 0; - } - - void addToCrc(uint8_t byte) - { - crc = (crc << 8) ^ (CRCTable[((crc >> 8) ^ byte) & 0xFF]); - } - - uint16_t crc; - static const uint16_t CRCTable[]; -}; - // Used by the Sky9x family boards class SerialPxxBitTransport: public DataBuffer { protected: uint8_t byte; uint8_t bits_count; - void initFrame() + void initFrame(uint32_t period) { initBuffer(); byte = 0; @@ -113,10 +102,10 @@ class PwmPxxBitTransport: public PulsesBuffer { protected: uint16_t rest; - void initFrame() + void initFrame(uint32_t period) { initBuffer(); - rest = PXX_PERIOD_HALF_US; + rest = period * 2000; // 0.5uS (2Mhz) } void addPart(uint8_t value) @@ -133,108 +122,10 @@ class PwmPxxBitTransport: public PulsesBuffer { } }; -template -class StandardPxxTransport: public BitTransport, public PxxCrcMixin { - protected: - uint8_t ones_count; - - void initFrame() - { - BitTransport::initFrame(); - ones_count = 0; - } - - void addByte(uint8_t byte) - { - PxxCrcMixin::addToCrc(byte); - addByteWithoutCrc(byte); - }; - - void addRawByteWithoutCrc(uint8_t byte) - { - for (uint8_t i = 0; i < 8; i++) { - if (byte & 0x80) - BitTransport::addPart(1); - else - BitTransport::addPart(0); - byte <<= 1; - } - } - - void addByteWithoutCrc(uint8_t byte) - { - for (uint8_t i = 0; i < 8; i++) { - addBit(byte & 0x80); - byte <<= 1; - } - } - - void addBit(uint8_t bit) - { - if (bit) { - BitTransport::addPart(1); - if (++ones_count == 5) { - ones_count = 0; - BitTransport::addPart(0); // Stuff a 0 bit in - } - } - else { - BitTransport::addPart(0); - ones_count = 0; - } - } -}; - -class UartPxxTransport: public DataBuffer, public PxxCrcMixin { - protected: - void initFrame() - { - initBuffer(); - } - - void addByte(uint8_t byte) - { - PxxCrcMixin::addToCrc(byte); - addWithByteStuffing(byte); - } - - void addRawByteWithoutCrc(uint8_t byte) - { - addByteWithoutCrc(byte); - } - - void addByteWithoutCrc(uint8_t byte) - { - *ptr++ = byte; - } - - void addWithByteStuffing(uint8_t byte) - { - if (0x7E == byte) { - *ptr++ = 0x7D; - *ptr++ = 0x5E; - } - else if (0x7D == byte) { - *ptr++ = 0x7D; - *ptr++ = 0x5D; - } - else { - *ptr++ = byte; - } - } - - void addTail() - { - // nothing - } -}; - template class PxxPulses: public PxxTransport { protected: - uint8_t addFlag1(uint8_t port); void addChannels(uint8_t port, uint8_t sendFailsafe, uint8_t sendUpperChannels); - void addExtraFlags(uint8_t port); }; #endif diff --git a/radio/src/pulses/pxx1.cpp b/radio/src/pulses/pxx1.cpp index 3ab3963d8..e11642b4e 100644 --- a/radio/src/pulses/pxx1.cpp +++ b/radio/src/pulses/pxx1.cpp @@ -21,8 +21,167 @@ #include "opentx.h" #include "pulses/pxx1.h" +const uint16_t Pxx1CrcMixin::CRCTable[] = { + 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, + 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, + 0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, + 0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, + 0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, + 0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, + 0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, + 0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, + 0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, + 0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, + 0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, + 0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, + 0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, + 0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, + 0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, + 0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, + 0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, + 0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, + 0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, + 0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, + 0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5, + 0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd, + 0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134, + 0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c, + 0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3, + 0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb, + 0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232, + 0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a, + 0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1, + 0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9, + 0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330, + 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 +}; + template -void Pxx1Pulses::add8ChannelsFrame(uint8_t port, uint8_t sendUpperChannels) +uint8_t Pxx1Pulses::addFlag1(uint8_t module) +{ + uint8_t flag1 = (g_model.moduleData[module].rfProtocol << 6); + if (moduleSettings[module].mode == MODULE_MODE_BIND) { + flag1 |= (g_eeGeneral.countryCode << 1) | PXX_SEND_BIND; + } + else if (moduleSettings[module].mode == MODULE_MODE_RANGECHECK) { + flag1 |= PXX_SEND_RANGECHECK; + } + else { + bool failsafeNeeded = g_model.moduleData[module].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[module].failsafeMode != FAILSAFE_RECEIVER; + if (moduleSettings[module].counter-- == 0) { + // counter is also used for knowing if the frame is odd / even + moduleSettings[module].counter = 1000; + if (failsafeNeeded) { + flag1 |= PXX_SEND_FAILSAFE; + } + } + if (failsafeNeeded && moduleSettings[module].counter == 0 && g_model.moduleData[module].channelsCount > 0) { + flag1 |= PXX_SEND_FAILSAFE; + } + } + PxxTransport::addByte(flag1); + return flag1; +} + +template +void Pxx1Pulses::addExtraFlags(uint8_t module) +{ + // Ext. flag (holds antenna selection on Horus internal module, 0x00 otherwise) + uint8_t extra_flags = 0; + +#if defined(PCBHORUS) || defined(PCBXLITE) + if (module == INTERNAL_MODULE) { + extra_flags |= (g_model.moduleData[module].pxx.external_antenna << 0); + } +#endif + + extra_flags |= (g_model.moduleData[module].pxx.receiver_telem_off << 1); + extra_flags |= (g_model.moduleData[module].pxx.receiver_channel_9_16 << 2); + if (isModuleR9M(module)) { + extra_flags |= (min(g_model.moduleData[module].pxx.power, isModuleR9M_FCC_VARIANT(module) ? (uint8_t)R9M_FCC_POWER_MAX : (uint8_t)R9M_LBT_POWER_MAX) << 3); + if (isModuleR9M_EUPLUS(module)) + extra_flags |= (1 << 6); + } + + // Disable S.PORT if internal module is active + if (IS_TELEMETRY_INTERNAL_MODULE()) { + extra_flags |= (1 << 5); + } + PxxTransport::addByte(extra_flags); +} + +template +void Pxx1Pulses::addChannels(uint8_t port, uint8_t sendFailsafe, uint8_t sendUpperChannels) +{ + uint16_t pulseValue = 0; + uint16_t pulseValueLow = 0; + + for (int8_t i=0; i<8; i++) { + if (sendFailsafe) { + if (g_model.moduleData[port].failsafeMode == FAILSAFE_HOLD) { + pulseValue = (i < sendUpperChannels ? 4095 : 2047); + } + else if (g_model.moduleData[port].failsafeMode == FAILSAFE_NOPULSES) { + pulseValue = (i < sendUpperChannels ? 2048 : 0); + } + else { + if (i < sendUpperChannels) { + int16_t failsafeValue = g_model.failsafeChannels[8+i]; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + pulseValue = 4095; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + pulseValue = 2048; + } + else { + failsafeValue += 2*PPM_CH_CENTER(8+g_model.moduleData[port].channelsStart+i) - 2*PPM_CENTER; + pulseValue = limit(2049, (failsafeValue * 512 / 682) + 3072, 4094); + } + } + else { + int16_t failsafeValue = g_model.failsafeChannels[i]; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + pulseValue = 2047; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + pulseValue = 0; + } + else { + failsafeValue += 2*PPM_CH_CENTER(g_model.moduleData[port].channelsStart+i) - 2*PPM_CENTER; + pulseValue = limit(1, (failsafeValue * 512 / 682) + 1024, 2046); + } + } + } + } + else { + if (i < sendUpperChannels) { + int channel = 8 + g_model.moduleData[port].channelsStart + i; + int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(2049, (value * 512 / 682) + 3072, 4094); + } + else if (i < sentModuleChannels(port)) { + int channel = g_model.moduleData[port].channelsStart + i; + int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); + } + else { + pulseValue = 1024; + } + } + + if (i & 1) { + PxxTransport::addByte(pulseValueLow); // Low byte of channel + PxxTransport::addByte(((pulseValueLow >> 8) & 0x0F) | (pulseValue << 4)); // 4 bits each from 2 channels + PxxTransport::addByte(pulseValue >> 4); // High byte of channel + } + else { + pulseValueLow = pulseValue; + } + } +} + +template +void Pxx1Pulses::add8ChannelsFrame(uint8_t module, uint8_t sendUpperChannels) { PxxTransport::initCrc(); @@ -30,19 +189,19 @@ void Pxx1Pulses::add8ChannelsFrame(uint8_t port, uint8_t sendUpper addHead(); // RX Number - PxxTransport::addByte(g_model.header.modelId[port]); + PxxTransport::addByte(g_model.header.modelId[module]); // Flag1 - uint8_t flag1 = PxxPulses::addFlag1(port); + uint8_t flag1 = addFlag1(module); // Flag2 PxxTransport::addByte(0); // Channels - PxxPulses::addChannels(port, flag1 & PXX_SEND_FAILSAFE, sendUpperChannels); + addChannels(module, flag1 & PXX_SEND_FAILSAFE, sendUpperChannels); // Extra flags - PxxPulses::addExtraFlags(port); + addExtraFlags(module); // CRC addCrc(); @@ -55,25 +214,28 @@ void Pxx1Pulses::add8ChannelsFrame(uint8_t port, uint8_t sendUpper } template -void Pxx1Pulses::setupFrame(uint8_t port) +void Pxx1Pulses::setupFrame(uint8_t module) { - PxxTransport::initFrame(); + PxxTransport::initFrame(PXX_PULSES_PERIOD); #if defined(PXX_FREQUENCY_HIGH) - add8ChannelsFrame(port, 0); - if (sentModuleChannels(port) > 8) { - add8ChannelsFrame(port, 8); + if (moduleSettings[module].protocol == PROTOCOL_CHANNELS_PXX1_SERIAL) { + add8ChannelsFrame(module, 0); + if (sentModuleChannels(module) > 8) { + add8ChannelsFrame(module, 8); + } + return; } -#else - static uint8_t pass[NUM_MODULES] = { MODULES_INIT(0) }; - uint8_t sendUpperChannels = 0; - if (pass[port]++ & 0x01) { - sendUpperChannels = g_model.moduleData[port].channelsCount; - } - add8ChannelsFrame(port, sendUpperChannels); #endif + + uint8_t sendUpperChannels = 0; + if (moduleSettings[module].counter & 0x01) { + sendUpperChannels = g_model.moduleData[module].channelsCount; + } + + add8ChannelsFrame(module, sendUpperChannels); } -template class Pxx1Pulses >; -template class Pxx1Pulses >; -template class Pxx1Pulses; +template class Pxx1Pulses >; +template class Pxx1Pulses >; +template class Pxx1Pulses; diff --git a/radio/src/pulses/pxx1.h b/radio/src/pulses/pxx1.h index d7d958b45..600a1cb4d 100644 --- a/radio/src/pulses/pxx1.h +++ b/radio/src/pulses/pxx1.h @@ -23,6 +23,118 @@ #include "pxx.h" +class Pxx1CrcMixin { + protected: + void initCrc() + { + crc = 0; + } + + void addToCrc(uint8_t byte) + { + crc = (crc << 8) ^ (CRCTable[((crc >> 8) ^ byte) & 0xFF]); + } + + uint16_t crc; + static const uint16_t CRCTable[]; +}; + +template +class StandardPxx1Transport: public BitTransport, public Pxx1CrcMixin { + protected: + uint8_t ones_count; + + void initFrame(uint32_t period) + { + BitTransport::initFrame(period); + ones_count = 0; + } + + void addByte(uint8_t byte) + { + Pxx1CrcMixin::addToCrc(byte); + addByteWithoutCrc(byte); + }; + + void addRawByte(uint8_t byte) + { + for (uint8_t i = 0; i < 8; i++) { + if (byte & 0x80) + BitTransport::addPart(1); + else + BitTransport::addPart(0); + byte <<= 1; + } + } + + void addByteWithoutCrc(uint8_t byte) + { + for (uint8_t i = 0; i < 8; i++) { + addBit(byte & 0x80); + byte <<= 1; + } + } + + void addBit(uint8_t bit) + { + if (bit) { + BitTransport::addPart(1); + if (++ones_count == 5) { + ones_count = 0; + BitTransport::addPart(0); // Stuff a 0 bit in + } + } + else { + BitTransport::addPart(0); + ones_count = 0; + } + } +}; + +class UartPxx1Transport: public DataBuffer, public Pxx1CrcMixin { + protected: + void initFrame(uint32_t period) + { + initBuffer(); + } + + void addByte(uint8_t byte) + { + Pxx1CrcMixin::addToCrc(byte); + addWithByteStuffing(byte); + } + + void addRawByte(uint8_t byte) + { + *ptr++ = byte; + } + + void addByteWithoutCrc(uint8_t byte) + { + addWithByteStuffing(byte); + } + + void addWithByteStuffing(uint8_t byte) + { + if (0x7E == byte) { + addRawByte(0x7D); + addRawByte(0x5E); + } + else if (0x7D == byte) { + addRawByte(0x7D); + addRawByte(0x5D); + } + else { + addRawByte(byte); + } + } + + void addTail() + { + // nothing + } +}; + template class Pxx1Pulses: public PxxPulses { @@ -33,20 +145,23 @@ class Pxx1Pulses: public PxxPulses void addHead() { // send 7E, do not CRC - PxxTransport::addRawByteWithoutCrc(0x7E); + PxxTransport::addRawByte(0x7E); } void addCrc() { - PxxTransport::addByteWithoutCrc(PxxCrcMixin::crc >> 8); - PxxTransport::addByteWithoutCrc(PxxCrcMixin::crc); + PxxTransport::addByteWithoutCrc(Pxx1CrcMixin::crc >> 8); + PxxTransport::addByteWithoutCrc(Pxx1CrcMixin::crc); } + uint8_t addFlag1(uint8_t port); + void addExtraFlags(uint8_t port); + void addChannels(uint8_t port, uint8_t sendFailsafe, uint8_t sendUpperChannels); void add8ChannelsFrame(uint8_t port, uint8_t sendUpperChannels); }; -typedef Pxx1Pulses UartPxxPulses; -typedef Pxx1Pulses> PwmPxxPulses; -typedef Pxx1Pulses> SerialPxxPulses; +typedef Pxx1Pulses UartPxx1Pulses; +typedef Pxx1Pulses> PwmPxx1Pulses; +typedef Pxx1Pulses> SerialPxx1Pulses; #endif diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index d7d32b588..9876d58ab 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -21,55 +21,318 @@ #include "opentx.h" #include "pulses/pxx2.h" -void Pxx2Pulses::setupFrame(uint8_t port) +uint8_t Pxx2Pulses::addFlag0(uint8_t module) { - initFrame(); - initCrc(); - - static uint8_t pass[NUM_MODULES] = { MODULES_INIT(0) }; - uint8_t sendUpperChannels = 0; - if (pass[port]++ & 0x01) { - sendUpperChannels = g_model.moduleData[port].channelsCount; + uint8_t flag0 = g_model.header.modelId[module] & 0x3F; + if (g_model.moduleData[module].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[module].failsafeMode != FAILSAFE_RECEIVER) { + if (moduleSettings[module].counter == 0) { + flag0 |= PXX2_CHANNELS_FLAG0_FAILSAFE; + } } + if (moduleSettings[module].mode == MODULE_MODE_RANGECHECK) { + flag0 |= PXX2_CHANNELS_FLAG0_RANGECHECK; + } + Pxx2Transport::addByte(flag0); + return flag0; +} - // Model ID - addByte(g_model.header.modelId[port]); +void Pxx2Pulses::addFlag1() +{ + uint8_t flag1 = 0; + Pxx2Transport::addByte(flag1); +} + +void Pxx2Pulses::addPulsesValues(uint16_t low, uint16_t high) +{ + Pxx2Transport::addByte(low); // Low byte of channel + Pxx2Transport::addByte(((low >> 8) & 0x0F) | (high << 4)); // 4 bits each from 2 channels + Pxx2Transport::addByte(high >> 4); // High byte of channel +} + +void Pxx2Pulses::addChannels(uint8_t module) +{ + uint16_t pulseValue = 0; + uint16_t pulseValueLow = 0; + + uint8_t channel = g_model.moduleData[module].channelsStart; + uint8_t count = sentModuleChannels(module); + + for (int8_t i = 0; i < count; i++, channel++) { + int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); + if (i & 1) + addPulsesValues(pulseValueLow, pulseValue); + else + pulseValueLow = pulseValue; + } +} + +void Pxx2Pulses::addFailsafe(uint8_t module) +{ + uint16_t pulseValue = 0; + uint16_t pulseValueLow = 0; + + uint8_t channel = g_model.moduleData[module].channelsStart; + uint8_t count = sentModuleChannels(module); + + for (int8_t i = 0; i < count; i++, channel++) { + if (g_model.moduleData[module].failsafeMode == FAILSAFE_HOLD) { + pulseValue = 2047; + } + else if (g_model.moduleData[module].failsafeMode == FAILSAFE_NOPULSES) { + pulseValue = 0; + } + else { + int16_t failsafeValue = g_model.failsafeChannels[channel]; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + pulseValue = 2047; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + pulseValue = 0; + } + else { + failsafeValue += 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(1, (failsafeValue * 512 / 682) + 1024, 2046); + } + } + if (i & 1) + addPulsesValues(pulseValueLow, pulseValue); + else + pulseValueLow = pulseValue; + } +} + +void Pxx2Pulses::setupChannelsFrame(uint8_t module) +{ + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_CHANNELS); + + // Flag0 + uint8_t flag0 = addFlag0(module); // Flag1 - uint8_t flag1 = addFlag1(port); + addFlag1(); - // Flag2 - addByte(0); + // Failsafe / Channels + if (flag0 & PXX2_CHANNELS_FLAG0_FAILSAFE) + addFailsafe(module); + else + addChannels(module); +} - // Channels - addChannels(port, flag1 & PXX_SEND_FAILSAFE, sendUpperChannels); +void Pxx2Pulses::setupTelemetryFrame(uint8_t module) +{ + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_TELEMETRY); + for (uint8_t i = 0; i < outputTelemetryBuffer.size; i++) { + Pxx2Transport::addByte(outputTelemetryBuffer.data[i]); + } + outputTelemetryBuffer.reset(); +} - // Extra flags - addExtraFlags(port); - - // Flag3, reserved - addByte(0); - -#if defined(LUA) - if (outputTelemetryBufferTrigger != 0x00 && outputTelemetryBufferSize > 0) { - // CMD/Resp - addByte(1); - // primID (1 byte) + dataID (2 bytes) + value (4 bytes) - for (uint8_t i=0; i<7; i++) { - addByte(outputTelemetryBuffer[i]); +void Pxx2Pulses::setupHardwareInfoFrame(uint8_t module) +{ + if (reusableBuffer.hardwareAndSettings.modules[module].current <= reusableBuffer.hardwareAndSettings.modules[module].maximum) { + if (reusableBuffer.hardwareAndSettings.modules[module].timeout == 0) { + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_HW_INFO); + Pxx2Transport::addByte(reusableBuffer.hardwareAndSettings.modules[module].current); + reusableBuffer.hardwareAndSettings.modules[module].timeout = 20; + reusableBuffer.hardwareAndSettings.modules[module].current++; + } + else { + reusableBuffer.hardwareAndSettings.modules[module].timeout--; + setupChannelsFrame(module); } - outputTelemetryBufferTrigger = 0x00; - outputTelemetryBufferSize = 0; } else { - // CMD/Resp - addByte(0); + moduleSettings[module].mode = MODULE_MODE_NORMAL; + setupChannelsFrame(module); } -#else - // CMD/Resp - addByte(0); -#endif - - // CRC - addByte(crc); // TODO need to check the CRC chosen algorithm } + +void Pxx2Pulses::setupRegisterFrame(uint8_t module) +{ + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_REGISTER); + + if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_RX_NAME_SELECTED) { + Pxx2Transport::addByte(0x01); + for (uint8_t i=0; i reusableBuffer.hardwareAndSettings.moduleSettings.timeout) { + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_TX_SETTINGS); + uint8_t flag0 = 0; + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_WRITE) + flag0 |= PXX2_TX_SETTINGS_FLAG0_WRITE; + Pxx2Transport::addByte(flag0); + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_WRITE) { + uint8_t flag1 = reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol << 4; + if (reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna) + flag1 |= PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA; + Pxx2Transport::addByte(flag1); + Pxx2Transport::addByte(reusableBuffer.hardwareAndSettings.moduleSettings.txPower); + } + reusableBuffer.hardwareAndSettings.moduleSettings.timeout = get_tmr10ms() + 200/*next try in 2s*/; + } + else { + setupChannelsFrame(module); + } +} + +void Pxx2Pulses::setupReceiverSettingsFrame(uint8_t module) +{ + if (get_tmr10ms() > reusableBuffer.hardwareAndSettings.receiverSettings.timeout) { + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETTINGS); + uint8_t flag0 = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId; + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_WRITE) + flag0 |= PXX2_RX_SETTINGS_FLAG0_WRITE; + Pxx2Transport::addByte(flag0); + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_WRITE) { + uint8_t flag1 = 0; + if (reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled) + flag1 |= PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED; + if (reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate) + flag1 |= PXX2_RX_SETTINGS_FLAG1_FASTPWM; + Pxx2Transport::addByte(flag1); + uint8_t outputsCount = min(24, reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount); + for (int i = 0; i < outputsCount; i++) { + Pxx2Transport::addByte(min(23, reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[i])); + } + } + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = get_tmr10ms() + 200/*next try in 2s*/; + } + else { + setupChannelsFrame(module); + } +} + +void Pxx2Pulses::setupBindFrame(uint8_t module) +{ + if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_WAIT) { + if (get_tmr10ms() > reusableBuffer.moduleSetup.pxx2.bindWaitTimeout) { + moduleSettings[module].mode = MODULE_MODE_NORMAL; + reusableBuffer.moduleSetup.pxx2.bindStep = BIND_OK; + POPUP_INFORMATION(STR_BIND_OK); + } + return; + } + + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_BIND); + + if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_RX_NAME_SELECTED) { + Pxx2Transport::addByte(0x01); + for (uint8_t i=0; i 1000) { + moduleSettings[module].counter = 1002; + return; + } + + moduleSettings[module].counter = 1002; + + addFrameType(PXX2_TYPE_C_POWER_METER, PXX2_TYPE_ID_SPECTRUM); + Pxx2Transport::addByte(0x00); + + reusableBuffer.spectrumAnalyser.freq = 2440000000; // 2440MHz + Pxx2Transport::addWord(reusableBuffer.spectrumAnalyser.freq); + + reusableBuffer.spectrumAnalyser.span = 40000000; // 40MHz + Pxx2Transport::addWord(reusableBuffer.spectrumAnalyser.span); + + reusableBuffer.spectrumAnalyser.step = 100000; // 100KHz + Pxx2Transport::addWord(reusableBuffer.spectrumAnalyser.step); +} + + +void Pxx2Pulses::setupPowerMeter(uint8_t module) +{ + if (moduleSettings[module].counter > 1000) { + moduleSettings[module].counter = 1002; + return; + } + + moduleSettings[module].counter = 1002; + + addFrameType(PXX2_TYPE_C_POWER_METER, PXX2_TYPE_ID_POWER_METER); + Pxx2Transport::addByte(0x00); + + Pxx2Transport::addWord(reusableBuffer.powerMeter.freq); +} + +void Pxx2Pulses::setupShareMode(uint8_t module) +{ + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_SHARE); + Pxx2Transport::addByte(reusableBuffer.moduleSetup.pxx2.shareReceiverId); +} + +void Pxx2Pulses::setupFrame(uint8_t module) +{ + initFrame(); + + switch (moduleSettings[module].mode) { + case MODULE_MODE_GET_HARDWARE_INFO: + setupHardwareInfoFrame(module); + break; + case MODULE_MODE_MODULE_SETTINGS: + setupModuleSettingsFrame(module); + break; + case MODULE_MODE_RECEIVER_SETTINGS: + setupReceiverSettingsFrame(module); + break; + case MODULE_MODE_REGISTER: + setupRegisterFrame(module); + break; + case MODULE_MODE_BIND: + setupBindFrame(module); + break; + case MODULE_MODE_SPECTRUM_ANALYSER: + setupSpectrumAnalyser(module); + break; + case MODULE_MODE_POWER_METER: + setupPowerMeter(module); + break; + case MODULE_MODE_SHARE: + setupShareMode(module); + break; + default: + if (outputTelemetryBuffer.size > 0 && outputTelemetryBuffer.destination == module) { + setupTelemetryFrame(module); + } + else { + setupChannelsFrame(module); + } + break; + } + + if (moduleSettings[module].counter-- == 0) { + moduleSettings[module].counter = 1000; + } + + endFrame(); +} + +template class PxxPulses; diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 939d0204d..be47b43ab 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -21,52 +21,202 @@ #ifndef _PULSES_PXX2_H_ #define _PULSES_PXX2_H_ +#include "fifo.h" +#include "io/frsky_pxx2.h" #include "./pxx.h" -class SportCrcMixin { +#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_TELEMETRY 0xFE + +#define PXX2_TYPE_C_POWER_METER 0x02 + #define PXX2_TYPE_ID_POWER_METER 0x01 + #define PXX2_TYPE_ID_SPECTRUM 0x02 + +#define PXX2_TYPE_C_OTA 0xFE + +#define PXX2_CHANNELS_FLAG0_FAILSAFE (1 << 6) +#define PXX2_CHANNELS_FLAG0_RANGECHECK (1 << 7) + +#define PXX2_RX_SETTINGS_FLAG0_WRITE (1 << 6) + +#define PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED (1 << 7) +#define PXX2_RX_SETTINGS_FLAG1_READONLY (1 << 6) +#define PXX2_RX_SETTINGS_FLAG1_FASTPWM (1 << 4) + +#define PXX2_TX_SETTINGS_FLAG0_WRITE (1 << 6) +#define PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA (1 << 3) + +#define PXX2_HW_INFO_TX_ID 0xFF + +enum PXX2RegisterSteps { + REGISTER_START, + REGISTER_RX_NAME_RECEIVED, + REGISTER_RX_NAME_SELECTED, + REGISTER_OK +}; + +enum PXX2BindSteps { + BIND_START, + BIND_RX_NAME_SELECTED, + BIND_WAIT, + BIND_OK +}; + +enum PXX2ReceiverStatus { + PXX2_HARDWARE_INFO, + PXX2_SETTINGS_READ, + PXX2_SETTINGS_WRITE, + PXX2_SETTINGS_OK +}; + +extern ModuleFifo intmoduleFifo; +extern ModuleFifo extmoduleFifo; + +class Pxx2CrcMixin { protected: void initCrc() { - crc = 0; + crc = 0xFFFF; } void addToCrc(uint8_t byte) { - crc += byte; // 0-1FF - crc += crc >> 8; // 0-100 - crc &= 0x00ff; + crc -= byte; } uint16_t crc; }; - -class Pxx2Transport: public DataBuffer, public SportCrcMixin { +class Pxx2Transport: public DataBuffer, public Pxx2CrcMixin { protected: - void addByte(uint8_t byte) + void addWord(uint32_t word) { - SportCrcMixin::addToCrc(byte); - *ptr++ = byte; + addByte(word); + addByte(word >> 8); + addByte(word >> 16); + addByte(word >> 24); } - void addTail() + void addByte(uint8_t byte) { - // nothing + Pxx2CrcMixin::addToCrc(byte); + addByteWithoutCrc(byte); + }; + + void addByteWithoutCrc(uint8_t byte) + { + *ptr++ = byte; } }; class Pxx2Pulses: public PxxPulses { public: - void setupFrame(uint8_t port); + void setupFrame(uint8_t module); protected: - uint8_t data[64]; - uint8_t * ptr; + void setupHardwareInfoFrame(uint8_t module); + + void setupRegisterFrame(uint8_t module); + + void setupBindFrame(uint8_t module); + + void setupShareMode(uint8_t module); + + void setupModuleSettingsFrame(uint8_t module); + + void setupReceiverSettingsFrame(uint8_t module); + + void setupChannelsFrame(uint8_t module); + + void setupTelemetryFrame(uint8_t module); + + void setupSpectrumAnalyser(uint8_t module); + + void setupPowerMeter(uint8_t module); + + void addHead() + { + // send 7E, do not CRC + Pxx2Transport::addByteWithoutCrc(0x7E); + + // reserve 1 byte for LEN + Pxx2Transport::addByteWithoutCrc(0x00); + } + + void addFrameType(uint8_t type_c, uint8_t type_id) + { + // TYPE_C + TYPE_ID + // TODO optimization ? Pxx2Transport::addByte(0x26); // This one is CRC-ed on purpose + + Pxx2Transport::addByte(type_c); + Pxx2Transport::addByte(type_id); + } + + uint8_t addFlag0(uint8_t module); + + void addFlag1(); + + void addPulsesValues(uint16_t low, uint16_t high); + + void addChannels(uint8_t module); + + void addFailsafe(uint8_t module); + + void addCrc() + { + Pxx2Transport::addByteWithoutCrc(Pxx2CrcMixin::crc >> 8); + Pxx2Transport::addByteWithoutCrc(Pxx2CrcMixin::crc); + } void initFrame() { + // init the CRC counter + initCrc(); + + // reset the frame pointer Pxx2Transport::initBuffer(); + + // add the frame head + addHead(); + } + + void endFrame() + { + uint8_t size = getSize() - 2; + + if (size > 0) { + // update the frame LEN = frame length minus the 2 first bytes + data[1] = getSize() - 2; + + // now add the CRC + addCrc(); + } + else { + Pxx2Transport::initBuffer(); + } } }; +union PXX2Version +{ + uint8_t major; + uint8_t minor:4; + uint8_t revision:4; +}; + +struct PXX2HardwareInformation +{ + uint8_t modelID; + PXX2Version hwVersion; + PXX2Version swVersion; + uint8_t variant; +}; + #endif diff --git a/radio/src/pulses/sbus_arm.cpp b/radio/src/pulses/sbus.cpp similarity index 81% rename from radio/src/pulses/sbus_arm.cpp rename to radio/src/pulses/sbus.cpp index 5824f17fe..26d4367b1 100644 --- a/radio/src/pulses/sbus_arm.cpp +++ b/radio/src/pulses/sbus.cpp @@ -48,17 +48,17 @@ static void _send_level(uint8_t v) { /* Copied over from DSM, this looks doubious and in my logic analyzer output the low->high is about 2 ns late */ - if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) + if (extmodulePulsesData.dsm2.index & 1) v += 2; else v -= 2; - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1; - modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1; - modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v; + *extmodulePulsesData.dsm2.ptr++ = v - 1; + extmodulePulsesData.dsm2.index+=1; + extmodulePulsesData.dsm2.rest -=v; } -void sendByteSbus(uint8_t b) //max 11 changes 0 10 10 10 10 P 1 +void sendByteSbus(uint8_t b) // max 11 changes 0 10 10 10 10 P 1 { bool lev = 0; uint8_t parity = 1; @@ -107,17 +107,17 @@ inline int getChannelValue(uint8_t port, int channel) return channelOutputs[ch] + 2 * PPM_CH_CENTER(ch) - 2*PPM_CENTER; } -void setupPulsesSbus(uint8_t port) +void setupPulsesSbus() { #if defined(PPM_PIN_SERIAL) - modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0; - modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0; + extmodulePulsesData.dsm2.serialByte = 0; + extmodulePulsesData.dsm2.serialBitCount = 0; #else - modulePulsesData[EXTERNAL_MODULE].dsm2.rest = SBUS_PERIOD_HALF_US; - modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; + extmodulePulsesData.dsm2.rest = SBUS_PERIOD_HALF_US; + extmodulePulsesData.dsm2.index = 0; #endif - modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses; // Sync Byte sendByteSbus(SBUS_FRAME_BEGIN_BYTE); @@ -127,7 +127,7 @@ void setupPulsesSbus(uint8_t port) // byte 1-22, channels 0..2047, limits not really clear (B for (int i=0; i 0) + if (getChannelValue(EXTERNAL_MODULE, 16) > 0) flags |=SBUS_FLAG_CHANNEL_17; - if (getChannelValue(port, 17) > 0) + if (getChannelValue(EXTERNAL_MODULE, 17) > 0) flags |=SBUS_FLAG_CHANNEL_18; sendByteSbus(flags); diff --git a/radio/src/rtos.h b/radio/src/rtos.h index 1478b778a..28532298b 100644 --- a/radio/src/rtos.h +++ b/radio/src/rtos.h @@ -27,14 +27,13 @@ extern "C++" { #endif -#define doNothing() do { } while(0) // seems unused? don't ever use this with SIMU - #if defined(SIMU) #include #include #define SIMU_SLEEP_OR_EXIT_MS(x) simuSleep(x) + #define RTOS_MS_PER_TICK 1 typedef pthread_t RTOS_TASK_HANDLE; typedef pthread_mutex_t RTOS_MUTEX_HANDLE; @@ -59,7 +58,7 @@ extern "C++" { static inline void RTOS_WAIT_TICKS(uint32_t x) { - RTOS_WAIT_MS(x * 2); + RTOS_WAIT_MS(x * RTOS_MS_PER_TICK); } #ifdef __cplusplus @@ -149,7 +148,7 @@ extern "C++" { } #endif - #define RTOS_MS_PER_TICK (CFG_CPU_FREQ / CFG_SYSTICK_FREQ / (CFG_CPU_FREQ / 1000)) // RTOS timer tick length in ms (currently 2) + #define RTOS_MS_PER_TICK ((CFG_CPU_FREQ / CFG_SYSTICK_FREQ) / (CFG_CPU_FREQ / 1000)) // RTOS timer tick length in ms (currently 2) typedef OS_TID RTOS_TASK_HANDLE; typedef OS_MutexID RTOS_MUTEX_HANDLE; diff --git a/radio/src/sbus.cpp b/radio/src/sbus.cpp index 6817fa0f1..e9b975144 100644 --- a/radio/src/sbus.cpp +++ b/radio/src/sbus.cpp @@ -30,11 +30,10 @@ #define SBUS_FAILSAFE_BIT 3 #define SBUS_CH_BITS 11 -#define SBUS_CH_MASK ((1<= 0; i--) { + if (path[i] == '/') { + return &path[i + 1]; + } + } + return path; +} + const char * getFileExtension(const char * filename, uint8_t size, uint8_t extMaxLen, uint8_t *fnlen, uint8_t *extlen) { int len = size; @@ -275,7 +285,7 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen lastpopupMenuOffset = 0; memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); } - else if (popupMenuOffset == popupMenuNoItems - MENU_MAX_DISPLAY_LINES) { + else if (popupMenuOffset == popupMenuItemsCount - MENU_MAX_DISPLAY_LINES) { lastpopupMenuOffset = 0xffff; memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); } @@ -292,14 +302,14 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); } - popupMenuNoItems = 0; + popupMenuItemsCount = 0; POPUP_MENU_SET_BSS_FLAG(); FRESULT res = f_opendir(&dir, path); if (res == FR_OK) { if (flags & LIST_NONE_SD_FILE) { - popupMenuNoItems++; + popupMenuItemsCount++; if (selection) { lastpopupMenuOffset++; } @@ -338,7 +348,7 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen continue; } - popupMenuNoItems++; + popupMenuItemsCount++; if (!(flags & LIST_SD_FILE_EXT)) { fno.fname[fnLen] = '\0'; // strip extension @@ -359,10 +369,9 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen } } } - for (uint8_t i=0; i=0; i--) { @@ -374,7 +383,7 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen break; } } - for (uint8_t i=0; i= 212 + lcdDrawRect(60, 6*FH+4, 132, 3); +#else + lcdDrawRect(10, 6*FH+4, 102, 3); +#endif + + // Models conversion + for (uint8_t id=0; id= 212 + lcdDrawSolidHorizontalLine(61, 6*FH+5, 10+id*2, FORCE); +#else + lcdDrawSolidHorizontalLine(11, 6*FH+5, 10+(id*3)/2, FORCE); +#endif + lcdRefresh(); + if (eeModelExists(id)) { + convertModelData(id, conversionVersionStart); + } + } + + return true; +} diff --git a/radio/src/storage/conversions/conversions.h b/radio/src/storage/conversions/conversions.h new file mode 100644 index 000000000..4da4a9ba7 --- /dev/null +++ b/radio/src/storage/conversions/conversions.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +bool eeConvert(); +void convertModelData(int id, int version); + +// Conversions 216 to 217 +void convertModelData_216_to_217(ModelData &model); +void convertRadioData_216_to_217(RadioData &settings); + +// Conversions 217 to 218 +void convertModelData_217_to_218(ModelData &model); +void convertRadioData_217_to_218(RadioData &settings); + +// Conversions 218 to 219 +void convertModelData_218_to_219(ModelData &model); +void convertRadioData_218_to_219(RadioData &settings); diff --git a/radio/src/storage/eeprom_conversions.cpp b/radio/src/storage/conversions/conversions_216_218.cpp similarity index 92% rename from radio/src/storage/eeprom_conversions.cpp rename to radio/src/storage/conversions/conversions_216_218.cpp index 0046fb2d1..ddce57aef 100644 --- a/radio/src/storage/eeprom_conversions.cpp +++ b/radio/src/storage/conversions/conversions_216_218.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "datastructs_218.h" enum Mix216Sources { MIXSRC216_NONE, @@ -376,22 +377,22 @@ PACK(typedef struct { int8_t swtch; uint8_t func; PACK(union { - PACK(struct { - char name[8]; - }) play; + PACK(struct { + char name[8]; + }) play; - PACK(struct { - int16_t val; - uint8_t mode; - uint8_t param; - int32_t spare2; - }) all; + PACK(struct { + int16_t val; + uint8_t mode; + uint8_t param; + int32_t spare2; + }) all; - PACK(struct { - int32_t val1; - int32_t val2; - }) clear; - }); + PACK(struct { + int32_t val1; + int32_t val2; + }) clear; + }); uint8_t active; }) CustomFunctionData_v216; #else @@ -436,8 +437,8 @@ typedef union { PACK(struct FrSkyChannelData_v216 { - uint8_t unused[7]; -}); + uint8_t unused[7]; + }); PACK(typedef struct { @@ -486,6 +487,34 @@ PACK(typedef struct { uint8_t ppmPulsePol; }) ModuleData_v216; +PACK(typedef struct { + uint8_t type:4; + int8_t rfProtocol:4; + uint8_t channelsStart; + int8_t channelsCount; // 0=8 channels + union { + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t subType:3; + uint8_t invertedSerial:1; // telemetry serial inverted from standard + }; + struct { + uint8_t failsafeMode:4; // only 3 bits used + uint8_t freq:2; + uint8_t region:2; + } r9m; + }; + int16_t failsafeChannels[MAX_OUTPUT_CHANNELS]; + union { + struct { + int8_t delay:6; + uint8_t pulsePol:1; + uint8_t outputType:1; // false = open drain, true = push pull + int8_t frameLength; + } ppm; + }; +}) ModuleData_v217; + #if defined(PCBTARANIS) #define MODELDATA_EXTRA_216 \ uint8_t externalModule; \ @@ -511,7 +540,7 @@ PACK(typedef struct { uint8_t spare:3; \ uint8_t trainerMode:3; \ uint8_t potsWarnMode:2; \ - ModuleData moduleData[NUM_MODULES+1]; \ + ModuleData_v217 moduleData[NUM_MODULES+1]; \ char curveNames[MAX_CURVES][6]; \ ScriptData scriptsData[MAX_SCRIPTS]; \ char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; \ @@ -521,7 +550,7 @@ PACK(typedef struct { #define MODELDATA_EXTRA_217 \ uint8_t spare:6; \ uint8_t potsWarnMode:2; \ - ModuleData moduleData[NUM_MODULES+1]; \ + ModuleData_v217 moduleData[NUM_MODULES+1]; \ uint8_t potsWarnEnabled; \ int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; \ uint8_t rxBattAlarms[2]; @@ -766,7 +795,7 @@ PACK(typedef struct { int8_t varioRange; int8_t varioRepeat; int8_t backgroundVolume; - + TARANIS_FIELD(uint8_t serial2Mode:6) TARANIS_FIELD(uint8_t slidersConfig:2) TARANIS_FIELD(uint8_t potsConfig) @@ -782,7 +811,7 @@ PACK(typedef struct { TARANIS_PCBX9E_FIELD(char bluetoothName[LEN_BLUETOOTH_NAME]) }) RadioData_v216; -void ConvertRadioData_216_to_217(RadioData & settings) +void convertRadioData_216_to_217(RadioData &settings) { RadioData_v216 * settings_v216 = (RadioData_v216 *)&settings; settings_v216->version = 217; @@ -792,11 +821,11 @@ void ConvertRadioData_216_to_217(RadioData & settings) #endif } -void ConvertSpecialFunctions_217_to_218(CustomFunctionData * cf218, CustomFunctionData_v216 * cf216) +void ConvertSpecialFunctions_217_to_218(CustomFunctionData_v218 * cf218, CustomFunctionData_v216 * cf216) { for (int i=0; i= 212 - lcdDrawRect(60, 6*FH+4, 132, 3); -#else - lcdDrawRect(10, 6*FH+4, 102, 3); -#endif - - // Models conversion - for (uint8_t id=0; id= 212 - lcdDrawSolidHorizontalLine(61, 6*FH+5, 10+id*2, FORCE); -#else - lcdDrawSolidHorizontalLine(11, 6*FH+5, 10+(id*3)/2, FORCE); -#endif - lcdRefresh(); - if (eeModelExists(id)) { - ConvertModel(id, conversionVersionStart); - } - - } - - return true; -} diff --git a/radio/src/storage/conversions/conversions_218_219.cpp b/radio/src/storage/conversions/conversions_218_219.cpp new file mode 100644 index 000000000..8b2983afc --- /dev/null +++ b/radio/src/storage/conversions/conversions_218_219.cpp @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#include "opentx.h" +#include "datastructs_218.h" + +/* + * PCBHORUS: 64 telemetry sensors instead of 32 + * ALL: ReceiverData array added + * ALL: registrationId added + * ALL: failsafeChannels moved from ModuleData to ModelData + * ALL: ModuleData / TrainerModuleData modified + * + */ + +typedef ModelData ModelData_v219; + +void convertModelData_218_to_219(ModelData &model) +{ + assert(sizeof(ModelData_v218) <= sizeof(ModelData)); + + ModelData_v218 oldModel; + memcpy(&oldModel, &model, sizeof(oldModel)); + ModelData_v219 & newModel = (ModelData_v219 &) model; + + memset(&newModel.rssiAlarms + sizeof(RssiAlarmData), 0, sizeof(ModelData_v219) - offsetof(ModelData_v219, rssiAlarms) - sizeof(RssiAlarmData)); + + char name[LEN_MODEL_NAME+1]; + zchar2str(name, oldModel.header.name, LEN_MODEL_NAME); + TRACE("Model %s conversion from v218 to v219", name); + + for (int i=0; i off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw + uint32_t start:23; + int32_t value:24; + uint32_t countdownBeep:2; + uint32_t minuteBeep:1; + uint32_t persistent:2; + int32_t countdownStart:2; + uint32_t direction:1; + char name[LEN_TIMER_NAME_218]; +}) TimerData_v218; + +PACK(typedef struct { + trim_t trim[NUM_STICKS]; + char name[LEN_FLIGHT_MODE_NAME_218]; + int16_t swtch:9; // swtch of phase[0] is not used + int16_t spare:7; + uint8_t fadeIn; + uint8_t fadeOut; + int16_t rotaryEncoders[1]; + gvar_t gvars[9]; +}) FlightModeData_v218; + +PACK(typedef struct { + int16_t weight:11; // GV1=-1024, -GV1=1023 + uint16_t destCh:5; + uint16_t srcRaw:10; // srcRaw=0 means not used + uint16_t carryTrim:1; + uint16_t mixWarn:2; // mixer warning + uint16_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := + uint16_t spare:1; + int32_t offset:14; + int32_t swtch:9; + uint32_t flightModes:9; + CurveRef curve; + uint8_t delayUp; + uint8_t delayDown; + uint8_t speedUp; + uint8_t speedDown; + char name[LEN_EXPOMIX_NAME_218]; +}) MixData_v218; + +PACK(typedef struct { + uint16_t mode:2; + uint16_t scale:14; + uint16_t srcRaw:10; + int16_t carryTrim:6; + uint32_t chn:5; + int32_t swtch:9; + uint32_t flightModes:9; + int32_t weight:8; + int32_t spare:1; + char name[LEN_EXPOMIX_NAME_218]; + int8_t offset; + CurveRef curve; +}) ExpoData_v218; + +PACK(typedef struct { + uint8_t type:1; + uint8_t smooth:1; + int8_t points:6; // describes number of points - 5 + char name[LEN_CURVE_NAME_218]; +}) CurveData_v218; + +PACK(typedef struct { + int16_t calib[4]; + TrainerMix mix[4]; +}) TrainerData_v218; + +PACK(typedef struct { // Logical Switches data + uint8_t func; + int32_t v1:10; + int32_t v3:10; + int32_t andsw:9; + uint32_t andswtype:1; + uint32_t spare:2; + int16_t v2; + uint8_t delay; + uint8_t duration; +}) LogicalSwitchData_v218; + +PACK(typedef struct { + int16_t swtch:9; + uint16_t func:7; + PACK(union { + PACK(struct { + char name[8]; + }) play; + + PACK(struct { + int16_t val; + uint8_t mode; + uint8_t param; + int32_t spare2; + }) all; + + PACK(struct { + int32_t val1; + int32_t val2; + }) clear; + }); + uint8_t active; +}) CustomFunctionData_v218; + +PACK(typedef struct { + char name[6]; + uint32_t min:12; + uint32_t max:12; + uint32_t popup:1; + uint32_t prec:1; + uint32_t unit:2; + uint32_t spare:4; +}) GVarData_v218; + +#if defined(PCBX12S) +#define MODELDATA_EXTRA_218 uint8_t spare:3;uint8_t trainerMode:3;uint8_t potsWarnMode:2; ModuleData_v218 moduleData[NUM_MODULES+1];ScriptData scriptsData[MAX_SCRIPTS_218];char inputNames[MAX_INPUTS_218][LEN_INPUT_NAME_218];;uint8_t potsWarnEnabled;;int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS];; +#elif defined(PCBX10) +#define MODELDATA_EXTRA_218 uint8_t spare:3;;uint8_t trainerMode:3;;uint8_t potsWarnMode:2;; ModuleData_v218 moduleData[NUM_MODULES+1];ScriptData scriptsData[MAX_SCRIPTS_218];;char inputNames[MAX_INPUTS_218][LEN_INPUT_NAME_218];;uint8_t potsWarnEnabled;;int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS];;uint8_t potsWarnSpares[NUM_DUMMY_ANAS];; +#elif defined(PCBTARANIS) +#define MODELDATA_EXTRA_218 uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData_v218 moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS_218]; char inputNames[MAX_INPUTS_218][LEN_INPUT_NAME_218]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; +#elif defined(PCBSKY9X) +#define MODELDATA_EXTRA_218 uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData_v218 moduleData[NUM_MODULES+1]; char inputNames[MAX_INPUTS_218][LEN_INPUT_NAME_218]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; uint8_t rxBattAlarms[2]; +#else + #define MODELDATA_EXTRA_218 +#endif + +PACK(typedef struct { + ModelHeader header; + TimerData_v218 timers[MAX_TIMERS_218]; + uint8_t telemetryProtocol:3; + uint8_t thrTrim:1; // Enable Throttle Trim + uint8_t noGlobalFunctions:1; + uint8_t displayTrims:2; + uint8_t ignoreSensorIds:1; + int8_t trimInc:3; // Trim Increments + uint8_t disableThrottleWarning:1; + uint8_t displayChecklist:1; + uint8_t extendedLimits:1; + uint8_t extendedTrims:1; + uint8_t throttleReversed:1; + BeepANACenter beepANACenter; + MixData_v218 mixData[MAX_MIXERS_218]; + LimitData limitData[MAX_OUTPUT_CHANNELS_218]; + ExpoData_v218 expoData[MAX_EXPOS_218]; + + CurveData_v218 curves[MAX_CURVES_218]; + int8_t points[MAX_CURVE_POINTS_218]; + + LogicalSwitchData_v218 logicalSw[32]; + CustomFunctionData_v218 customFn[MAX_SPECIAL_FUNCTIONS_218]; + SwashRingData swashR; + FlightModeData_v218 flightModeData[MAX_FLIGHT_MODES_218]; + + uint8_t thrTraceSrc; + + swarnstate_t switchWarningState; + swarnenable_t switchWarningEnable; + + GVarData_v218 gvars[MAX_GVARS_218]; + + FrSkyTelemetryData frsky; + RssiAlarmData rssiAlarms; + + MODELDATA_EXTRA_218 + + TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS_218]; + + TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer) +}) ModelData_v218; + +#define EXTRA_GENERAL_FIELDS_GENERAL_218 \ + uint8_t backlightBright; \ + uint32_t globalTimer; \ + uint8_t bluetoothBaudrate:4; \ + uint8_t bluetoothMode:4; \ + uint8_t countryCode; \ + uint8_t imperial:1; \ + uint8_t jitterFilter:1; /* 0 - active */\ + uint8_t disableRssiPoweroffAlarm:1; \ + uint8_t USBMode:2; \ + uint8_t spareExtraArm:3; \ + char ttsLanguage[2]; \ + int8_t beepVolume:4; \ + int8_t wavVolume:4; \ + int8_t varioVolume:4; \ + int8_t backgroundVolume:4; \ + int8_t varioPitch; \ + int8_t varioRange; \ + int8_t varioRepeat; \ + CustomFunctionData_v218 customFn[MAX_SPECIAL_FUNCTIONS_218]; + +#if defined(PCBHORUS) +#define EXTRA_GENERAL_FIELDS_218 \ + EXTRA_GENERAL_FIELDS_GENERAL_218 \ + uint8_t serial2Mode:4; \ + uint8_t slidersConfig:4; \ + uint32_t switchConfig; \ + uint8_t potsConfig; /* two bits per pot */ \ + char switchNames[NUM_SWITCHES_218][LEN_SWITCH_NAME_218]; \ + char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_DUMMY_ANAS][LEN_ANA_NAME_218]; \ + char currModelFilename[LEN_MODEL_FILENAME_218+1]; \ + uint8_t spare:1; \ + uint8_t blOffBright:7; \ + char bluetoothName[LEN_BLUETOOTH_NAME_218]; +#elif defined(PCBTARANIS) +#if defined(BLUETOOTH) +#define BLUETOOTH_FIELDS_218 \ + uint8_t spare; \ + char bluetoothName[LEN_BLUETOOTH_NAME_218]; +#else +#define BLUETOOTH_FIELDS +#endif +#define EXTRA_GENERAL_FIELDS_218 \ + EXTRA_GENERAL_FIELDS_GENERAL_218 \ + uint8_t serial2Mode:4; \ + uint8_t slidersConfig:4; \ + uint8_t potsConfig; /* two bits per pot */\ + uint8_t backlightColor; \ + swarnstate_t switchUnlockStates; \ + swconfig_t switchConfig; \ + char switchNames[NUM_SWITCHES_218][LEN_SWITCH_NAME_218]; \ + char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME_218]; \ + BLUETOOTH_FIELDS +#elif defined(PCBSKY9X) +#define EXTRA_GENERAL_FIELDS_218 \ + EXTRA_GENERAL_FIELDS_GENERAL_218 \ + int8_t txCurrentCalibration; \ + int8_t temperatureWarn; \ + uint8_t mAhWarn; \ + uint16_t mAhUsed; \ + int8_t temperatureCalib; \ + uint8_t optrexDisplay; \ + 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]; +#elif defined(CPUARM) + #define EXTRA_GENERAL_FIELDS_218 EXTRA_GENERAL_FIELDS_GENERAL_218 +#elif defined(PXX) + #define EXTRA_GENERAL_FIELDS_218 uint8_t countryCode; +#else + #define EXTRA_GENERAL_FIELDS_218 +#endif + +#if defined(PCBHORUS) +#define SPLASH_MODE_218 uint8_t splashSpares:3 +#elif defined(FSPLASH) +#define SPLASH_MODE_218 uint8_t splashMode:3 +#else +#define SPLASH_MODE_218 int8_t splashMode:3 +#endif + +PACK(typedef struct { + uint8_t version; + uint16_t variant; + CalibData calib[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS+NUM_DUMMY_ANAS]; + uint16_t chkSum; + N_HORUS_FIELD(int8_t currModel); + N_HORUS_FIELD(uint8_t contrast); + uint8_t vBatWarn; + int8_t txVoltageCalibration; + int8_t backlightMode; + TrainerData_v218 trainer; + uint8_t view; // index of view in main screen + BUZZER_FIELD_218 + uint8_t fai:1; + int8_t beepMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all + uint8_t alarmsFlash:1; + uint8_t disableMemoryWarning:1; + uint8_t disableAlarmWarning:1; + uint8_t stickMode:2; + int8_t timezone:5; + uint8_t adjustRTC:1; + uint8_t inactivityTimer; + SPLASH_MODE_218; /* 3bits */ + int8_t hapticMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all + uint8_t lightAutoOff; + uint8_t templateSetup; // RETA order for receiver channels + int8_t PPM_Multiplier; + int8_t hapticLength; + N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t reNavigation)); + N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t stickReverse)); + int8_t beepLength:3; + int8_t hapticStrength:3; + uint8_t gpsFormat:1; + uint8_t unexpectedShutdown:1; + uint8_t speakerPitch; + int8_t speakerVolume; + int8_t vBatMin; + int8_t vBatMax; + + EXTRA_GENERAL_FIELDS_218 + + THEME_DATA +}) RadioData_v218; + +#endif //OPENTX_DATASTRUCTS_218_H diff --git a/radio/src/storage/datacopy.cpp b/radio/src/storage/datacopy.cpp index 8b4d95cdd..ebbca4595 100644 --- a/radio/src/storage/datacopy.cpp +++ b/radio/src/storage/datacopy.cpp @@ -1,4 +1,4 @@ -//This file was auto-generated by generate_datacopy.py script on Mon Jul 2 14:20:48 2018. Do not edit this file! +//This file was auto-generated by generate_datacopy.py script on Tue Mar 19 19:58:50 2019. Do not edit this file! @@ -193,6 +193,27 @@ void copyTelemetrySensor(A * dest, B * src) dest->param = src->param; } +template +void copyTrainerModuleData(A * dest, B * src) +{ + dest->mode = src->mode; + dest->spare = src->spare; + dest->channelsStart = src->channelsStart; + dest->channelsCount = src->channelsCount; + dest->frameLength = src->frameLength; + dest->delay = src->delay; + dest->pulsePol = src->pulsePol; +} + +template +void copyReceiverData(A * dest, B * src) +{ + dest->used = src->used; + dest->telemetry = src->telemetry; + dest->dirty = src->dirty; + memcpy(dest->name, src->name, sizeof(dest->name)); +} + template void copyModuleData(A * dest, B * src) { @@ -200,10 +221,7 @@ void copyModuleData(A * dest, B * src) dest->rfProtocol = src->rfProtocol; dest->channelsStart = src->channelsStart; dest->channelsCount = src->channelsCount; - dest->failsafeMode = src->failsafeMode; - dest->subType = src->subType; - dest->invertedSerial = src->invertedSerial; - memcpy(dest->failsafeChannels, src->failsafeChannels, sizeof(dest->failsafeChannels)); + copyModuleData_r9m(&dest->r9m, &src->r9m); copyModuleData_ppm(&dest->ppm, &src->ppm); } @@ -266,9 +284,15 @@ void copyModelData(A * dest, B * src) for (int i=0; i<9; i++) { copyGVarData(&dest->gvars[i], &src->gvars[i]); } - for (int i=0; i<3; i++) { + for (int i=0; i<2; i++) { copyModuleData(&dest->moduleData[i], &src->moduleData[i]); } + for (int i=0; i<10; i++) { + copyReceiverData(&dest->receiverData[i], &src->receiverData[i]); + } + memcpy(dest->failsafeChannels, src->failsafeChannels, sizeof(dest->failsafeChannels)); + copyTrainerModuleData(&dest->trainerData, &src->trainerData); + memcpy(dest->modelRegistrationID, src->modelRegistrationID, sizeof(dest->modelRegistrationID)); } template @@ -306,6 +330,7 @@ void copyRadioData(A * dest, B * src) for (int i=0; i<13; i++) { copyCalibData(&dest->calib[i], &src->calib[i]); } + dest->spareRadio = src->spareRadio; dest->stickMode = src->stickMode; dest->telemetryBaudrate = src->telemetryBaudrate; dest->splashSpares = src->splashSpares; @@ -316,6 +341,7 @@ void copyRadioData(A * dest, B * src) dest->slidersConfig = src->slidersConfig; dest->switchConfig = src->switchConfig; dest->potsConfig = src->potsConfig; + memcpy(dest->ownerRegistrationID, src->ownerRegistrationID, sizeof(dest->ownerRegistrationID)); } template @@ -326,6 +352,14 @@ void copyCustomFunctionData_all(A * dest, B * src) dest->param = src->param; } +template +void copyModuleData_r9m(A * dest, B * src) +{ + dest->failsafeMode = src->failsafeMode; + dest->freq = src->freq; + dest->region = src->region; +} + template void copyModuleData_ppm(A * dest, B * src) { diff --git a/radio/src/storage/eeprom_common.h b/radio/src/storage/eeprom_common.h index 0e994dc16..00c840c03 100644 --- a/radio/src/storage/eeprom_common.h +++ b/radio/src/storage/eeprom_common.h @@ -25,8 +25,6 @@ uint16_t eeLoadGeneralSettingsData(); bool eeModelExists(uint8_t id); void eeLoadModel(uint8_t id); -bool eeConvert(); -void ConvertModel(int id, int version); uint8_t eeFindEmptyModel(uint8_t id, bool down); void selectModel(uint8_t sub); diff --git a/radio/src/storage/eeprom_raw.cpp b/radio/src/storage/eeprom_raw.cpp index 78ec6f677..b7867d7d7 100644 --- a/radio/src/storage/eeprom_raw.cpp +++ b/radio/src/storage/eeprom_raw.cpp @@ -23,6 +23,7 @@ #include #include "opentx.h" #include "timers.h" +#include "conversions/conversions.h" #define EEPROM_MARK 0x84697771 /* thanks ;) */ #define EEPROM_ZONE_SIZE (8*1024) @@ -584,7 +585,7 @@ const char * eeRestoreModel(uint8_t i_fileDst, char *model_name) #if defined(EEPROM_CONVERSIONS) if (version < EEPROM_VER) { - ConvertModel(i_fileDst, version); + convertModelData(i_fileDst, version); eeLoadModel(g_eeGeneral.currModel); } #endif diff --git a/radio/src/storage/eeprom_raw.h b/radio/src/storage/eeprom_raw.h index 64ac9f182..ca2b50f82 100644 --- a/radio/src/storage/eeprom_raw.h +++ b/radio/src/storage/eeprom_raw.h @@ -29,8 +29,6 @@ void eeDeleteModel( uint8_t id ) ; bool eeCopyModel(uint8_t dst, uint8_t src); void eeSwapModels(uint8_t id1, uint8_t id2); -#define DISPLAY_PROGRESS_BAR(x) - #if defined(SDCARD) const char * eeBackupModel(uint8_t i_fileSrc); const char * eeRestoreModel(uint8_t i_fileDst, char *model_name); diff --git a/radio/src/storage/eeprom_rlc.cpp b/radio/src/storage/eeprom_rlc.cpp index 81a621790..4eda3f925 100644 --- a/radio/src/storage/eeprom_rlc.cpp +++ b/radio/src/storage/eeprom_rlc.cpp @@ -22,6 +22,7 @@ #include #include "opentx.h" #include "timers.h" +#include "conversions/conversions.h" uint8_t s_write_err = 0; // error reasons RlcFile theFile; //used for any file operation @@ -467,7 +468,7 @@ const char * eeBackupModel(uint8_t i_fileSrc) len = i+1; if (len) { if (buf[i]) - buf[i] = idx2char(buf[i]); + buf[i] = zchar2char(buf[i]); else buf[i] = '_'; } @@ -596,7 +597,7 @@ const char * eeRestoreModel(uint8_t i_fileDst, char *model_name) #if defined(EEPROM_CONVERSIONS) if (version < EEPROM_VER) { storageCheck(true); - ConvertModel(i_fileDst, version); + convertModelData(i_fileDst, version); eeLoadModel(g_eeGeneral.currModel); } #endif @@ -615,9 +616,6 @@ void RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t *buf, uint16_t i_l m_rlc_buf = buf; m_rlc_len = i_len; m_cur_rlc_len = 0; -#if defined (EEPROM_PROGRESS_BAR) - m_ratio = (typ == FILE_TYP_MODEL ? 100 : 10); -#endif do { nextRlcWriteStep(); @@ -742,17 +740,6 @@ void RlcFile::flush() ENABLE_SYNC_WRITE(false); } -#if defined (EEPROM_PROGRESS_BAR) -void RlcFile::drawProgressBar(uint8_t x) -{ - if (storageDirtyMsk || isWriting() || eeprom_buffer_size) { - uint8_t len = storageDirtyMsk ? 1 : limit((uint8_t)1, (uint8_t)(7 - (m_rlc_len/m_ratio)), (uint8_t)7); - lcdDrawFilledRect(x+1, 0, 5, FH, SOLID, ERASE); - lcdDrawFilledRect(x+2, 7-len, 3, len); - } -} -#endif - // For conversions ... uint16_t eeLoadGeneralSettingsData() { @@ -880,7 +867,7 @@ void eeDeleteModel(uint8_t idx) #if defined(SDCARD) void eepromBackup() { - char filename[60]; + char path[60]; uint8_t buffer[1024]; FIL file; @@ -897,20 +884,20 @@ void eepromBackup() } // prepare the filename... - char * tmp = strAppend(filename, EEPROMS_PATH "/eeprom"); + char * tmp = strAppend(path, EEPROMS_PATH "/eeprom"); #if defined(RTCLOCK) tmp = strAppendDate(tmp, true); #endif strAppend(tmp, EEPROM_EXT); // open the file for writing... - f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS); + f_open(&file, path, FA_WRITE | FA_CREATE_ALWAYS); for (int i=0; i= 10 ? hex-9 : 27+hex); } -char idx2char(int8_t idx) +char zchar2char(int8_t idx) { if (idx == 0) return ' '; if (idx < 0) { @@ -44,7 +44,7 @@ char idx2char(int8_t idx) return ' '; } -int8_t char2idx(char c) +int8_t char2zchar(char c) { if (c == '_') return 37; #if LEN_SPECIAL_CHARS > 0 @@ -63,14 +63,14 @@ void str2zchar(char * dest, const char * src, int size) { memset(dest, 0, size); for (int c=0; c 0) { @@ -122,7 +132,7 @@ char * strcat_zchar(char * dest, const char * name, uint8_t size, const char * d len = i+1; if (len) { if (dest[i]) - dest[i] = idx2char(dest[i]); + dest[i] = zchar2char(dest[i]); else dest[i] = '_'; } @@ -266,7 +276,7 @@ char * getSwitchString(char * dest, swsrc_t idx) else *s++ = 'A'+swinfo.quot; #else - *s++ = 'A'+swinfo.quot; + *s++ = 'A' + swinfo.quot; #endif } *s++ = "\300-\301"[swinfo.rem]; diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 7eb1f12af..c180f67aa 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -132,17 +132,29 @@ void getSwitchesPosition(bool startup) CHECK_3POS(0, SW_SA); CHECK_3POS(1, SW_SB); CHECK_3POS(2, SW_SC); +#if !defined(PCBX3) CHECK_3POS(3, SW_SD); -#if !defined(PCBX7) && !defined(PCBXLITE) +#endif +#if defined(PCBXLITES) || defined(PCBX3) + CHECK_2POS(SW_SE); +#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) + // No SE +#else CHECK_3POS(4, SW_SE); #endif -#if !defined(PCBXLITE) +#if defined(PCBXLITE) && !defined(PCBXLITES) + // No SF +#else CHECK_2POS(SW_SF); #endif -#if !defined(PCBX7) && !defined(PCBXLITE) +#if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) + // No SG +#else CHECK_3POS(5, SW_SG); #endif -#if !defined(PCBXLITE) +#if defined(PCBXLITE) || defined(PCBX3) + // No SH +#else CHECK_2POS(SW_SH); #endif #if defined(PCBX9E) diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 51110e88b..d60248f3a 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -8,6 +8,7 @@ option(TRACE_FATFS "Traces FatFS enabled" OFF) option(TRACE_AUDIO "Traces audio enabled" OFF) option(DEBUG_TRACE_BUFFER "Debug Trace Screen" OFF) option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" OFF) +option(CROSSFIRE "Crossfire TX Module" OFF) option(SUPPORT_D16_EU_ONLY "XJT module only supports D16-EU and LR12-EU" OFF) # TODO rename to XJT_EU_ONLY option(DEBUG_INTERRUPTS "Count interrupts" OFF) option(DEBUG_USB_INTERRUPTS "Count individual USB interrupts" OFF) @@ -19,27 +20,33 @@ if(TIMERS EQUAL 3) else() add_definitions(-DTIMERS=2) endif() + if(LOG_TELEMETRY) add_definitions(-DLOG_TELEMETRY) endif() + if(TRACE_SD_CARD) add_definitions(-DTRACE_SD_CARD) set(DEBUG ON) set(DEBUG_TRACE_BUFFER ON) endif() + if(TRACE_FATFS) add_definitions(-DTRACE_FATFS) set(DEBUG ON) set(DEBUG_TRACE_BUFFER ON) endif() + if(TRACE_AUDIO) add_definitions(-DTRACE_AUDIO) set(DEBUG ON) set(DEBUG_TRACE_BUFFER ON) endif() + if(DEBUG_TRACE_BUFFER) add_definitions(-DDEBUG_TRACE_BUFFER) endif() + if(DEBUG_INTERRUPTS) add_definitions(-DDEBUG_INTERRUPTS) set(DEBUG ON) @@ -47,14 +54,17 @@ if(DEBUG_INTERRUPTS) add_definitions(-DDEBUG_USB_INTERRUPTS) endif() endif() + if(DEBUG_TASKS) add_definitions(-DDEBUG_TASKS) set(DEBUG ON) endif() + if(DEBUG_TIMERS) add_definitions(-DDEBUG_TIMERS) set(DEBUG ON) endif() + if(CLI) add_definitions(-DCLI) set(FIRMWARE_SRC ${FIRMWARE_SRC} cli.cpp) @@ -62,23 +72,61 @@ if(CLI) elseif(DEBUG) set(SRC ${SRC} dump.cpp) endif() + if(DEBUG) add_definitions(-DDEBUG) endif() + if(SUPPORT_D16_EU_ONLY) add_definitions(-DMODULE_D16_EU_ONLY_SUPPORT) endif() + if(HAPTIC) add_definitions(-DHAPTIC) set(SRC ${SRC} haptic.cpp) set(TARGET_SRC ${TARGET_SRC} haptic_driver.cpp) endif() + +# Protocols supported + +add_definitions(-DDSM2 -DSBUS) + +if(PXX1) + add_definitions(-DPXX -DPXX1) + set(PULSES_SRC + ${PULSES_SRC} + pxx1.cpp + ) +endif() + +if(PXX2) + add_definitions(-DPXX -DPXX2) + set(PULSES_SRC + ${PULSES_SRC} + pxx2.cpp + ) +endif() + if(MULTIMODULE) add_definitions(-DMULTIMODULE) - set(SRC ${SRC} pulses/multi_arm.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/multi.cpp) endif() + +if(CROSSFIRE) + add_definitions(-DCROSSFIRE) + set(PULSES_SRC + ${PULSES_SRC} + crossfire.cpp + ) + set(SRC + ${SRC} + telemetry/crossfire.cpp + ) +endif() + add_definitions(-DCPUARM) -add_definitions(-DTELEMETRY_FRSKY -DTELEMETRY_FRSKY_SPORT -DGPS -DPXX -DDSM2) +add_definitions(-DTELEMETRY_FRSKY -DTELEMETRY_FRSKY_SPORT -DGPS) + add_definitions(-DBOLD_FONT -DBATTGRAPH -DTHRTRACE) add_definitions(-DREQUIRED_SDCARD_VERSION="${SDCARD_VERSION}") include_directories(${COOS_DIR} ${COOS_DIR}/kernel ${COOS_DIR}/portable) @@ -86,31 +134,36 @@ foreach(LANGUAGE ${TTS_LANGUAGES}) string(TOLOWER ${LANGUAGE} lang_lower) set(SRC ${SRC} translations/tts_${lang_lower}.cpp) endforeach() + set(SRC ${SRC} - main_arm.cpp - tasks_arm.cpp - audio_arm.cpp + main.cpp + tasks.cpp + audio.cpp io/frsky_sport.cpp telemetry/telemetry.cpp telemetry/telemetry_holders.cpp telemetry/telemetry_sensors.cpp telemetry/frsky.cpp - telemetry/frsky_d_arm.cpp + telemetry/frsky_d.cpp telemetry/frsky_sport.cpp + telemetry/frsky_pxx2.cpp crc16.cpp vario.cpp ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} diskio.cpp ) + set(TARGET_SRC ${TARGET_SRC} pulses_driver.cpp keys_driver.cpp telemetry_driver.cpp ) + set(FIRMWARE_SRC ${FIRMWARE_SRC} ${COOS_DIR}/kernel/core.c @@ -128,17 +181,8 @@ set(FIRMWARE_SRC set(PULSES_SRC ${PULSES_SRC} - pulses_arm.cpp - ppm_arm.cpp - pxx.cpp - pxx1.cpp - dsm2_arm.cpp - sbus_arm.cpp + pulses.cpp + ppm.cpp + dsm2.cpp + sbus.cpp ) - -if(PXX2) - set(PULSES_SRC - ${PULSES_SRC} - pxx2.cpp - ) -endif() diff --git a/radio/src/targets/common/arm/stm32/CMakeLists.txt b/radio/src/targets/common/arm/stm32/CMakeLists.txt index 0398e2f74..e99cde823 100644 --- a/radio/src/targets/common/arm/stm32/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/CMakeLists.txt @@ -8,7 +8,7 @@ option(USB_SERIAL "Enable USB serial (CDC)" OFF) set(ARCH ARM) set(STM32USB_DIR ${THIRDPARTY_DIR}/STM32_USB-Host-Device_Lib_V2.2.0/Libraries) -add_definitions(-DSTM32 -DLUA_INPUTS -DVARIO -DCROSSFIRE) +add_definitions(-DSTM32 -DLUA_INPUTS -DVARIO) include_directories(${RADIO_SRC_DIRECTORY}/targets/common/arm/stm32) include_directories(${STM32USB_DIR}/STM32_USB_OTG_Driver/inc) @@ -53,6 +53,7 @@ if(DEBUG OR CLI OR USB_SERIAL) ) add_definitions(-DUSB_SERIAL) endif() + set(STM32USB_SRC ${STM32USB_SRC} STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c @@ -60,31 +61,37 @@ set(STM32USB_SRC STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ../common/arm/stm32/usbd_storage_msd.cpp ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ../common/arm/stm32/usbd_hid_joystick.c ) + if(GVARS) set(GUI_SRC ${GUI_SRC} ${GVAR_SCREEN} ) endif() + set(FIRMWARE_SRC ${FIRMWARE_SRC} serial.cpp syscalls.c ) + foreach(FILE ${STM32LIB_SRC}) set(FIRMWARE_SRC ${FIRMWARE_SRC} ${STM32LIB_DIR}/${FILE} ) endforeach() + foreach(FILE ${STM32USB_SRC}) set(FIRMWARE_SRC ${FIRMWARE_SRC} @@ -94,11 +101,5 @@ endforeach() set(SRC ${SRC} - telemetry/crossfire.cpp io/bootloader_flash.cpp ) - -set(PULSES_SRC - ${PULSES_SRC} - crossfire.cpp - ) diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index a96cfe8e3..eea2776fe 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -38,6 +38,8 @@ const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, 1,1,-1, 1,1, 1}; #elif defined(PCBX7) const int8_t ana_direction[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1}; +#elif defined(PCBX3) + const int8_t ana_direction[NUM_ANALOGS] = {-1,1,-1,1, 1,1}; #elif defined(PCBXLITE) const int8_t ana_direction[NUM_ANALOGS] = {1,-1,-1,1, -1,1, 1}; #elif defined(REV4a) @@ -58,7 +60,7 @@ #define NUM_ANALOGS_ADC NUM_ANALOGS #endif -uint16_t adcValues[NUM_ANALOGS] __DMA; +uint16_t adcValues[NUM_ANALOGS + 1/*RTC*/] __DMA; void adcInit() { @@ -90,7 +92,7 @@ void adcInit() ADC_MAIN->CR1 = ADC_CR1_SCAN; ADC_MAIN->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_MAIN->SQR1 = (NUM_ANALOGS_ADC-1) << 20; // bits 23:20 = number of conversions + ADC_MAIN->SQR1 = (NUM_ANALOGS_ADC + 1/*RTC*/ - 1) << 20; // bits 23:20 = number of conversions #if defined(PCBX10) if (STICKS_PWM_ENABLED()) { @@ -102,23 +104,26 @@ void adcInit() ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 } #elif defined(PCBX9E) - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT4<<0) + (ADC_CHANNEL_SLIDER3<<5) + (ADC_CHANNEL_SLIDER4<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more + ADC_MAIN->SQR2 = (ADC_CHANNEL_POT4<<0) + (ADC_CHANNEL_SLIDER3<<5) + (ADC_CHANNEL_SLIDER4<<10) + (ADC_CHANNEL_BATT<<15) + (ADC_CHANNEL_RTC<<20); // conversions 7 and more ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT2<<20) + (ADC_CHANNEL_POT3<<25); // conversions 1 to 6 #elif defined(PCBXLITE) if (STICKS_PWM_ENABLED()) { ADC_MAIN->SQR2 = 0; - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_BATT<<10); + ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_BATT<<10) + (ADC_CHANNEL_RTC<<15); } else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0); + ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0) + (ADC_CHANNEL_RTC<<5); ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 } #elif defined(PCBX7) // TODO why do we invert POT1 and POT2 here? - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0); // conversions 7 and more + ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0) + (ADC_CHANNEL_RTC<<5); // conversions 7 and more ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<25) + (ADC_CHANNEL_POT2<<20); // conversions 1 to 6 +#elif defined(PCBX3) + ADC_MAIN->SQR2 = (ADC_CHANNEL_RTC<<0); // conversions 7 and more + ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_BATT<<25); // conversions 1 to 6 #else - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more + ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15) + (ADC_CHANNEL_RTC<<20); // conversions 7 and more ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 #endif @@ -130,13 +135,13 @@ void adcInit() ADC_DMA_Stream->CR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; ADC_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_MAIN->DR); ADC_DMA_Stream->M0AR = CONVERT_PTR_UINT(&adcValues[FIRST_ANALOG_ADC]); - ADC_DMA_Stream->NDTR = NUM_ANALOGS_ADC; + ADC_DMA_Stream->NDTR = NUM_ANALOGS_ADC + 1/*RTC*/; ADC_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; #if defined(PCBX9E) ADC_EXT->CR1 = ADC_CR1_SCAN; ADC_EXT->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_EXT->SQR1 = (NUM_ANALOGS_ADC_EXT-1) << 20; + ADC_EXT->SQR1 = (NUM_ANALOGS_ADC_EXT - 1) << 20; ADC_EXT->SQR2 = 0; ADC_EXT->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10); // conversions 1 to 3 ADC_EXT->SMPR1 = 0; @@ -223,6 +228,14 @@ void adcStop() { } +uint16_t getRTCBattVoltage() +{ + ADC->CCR |= ADC_CCR_VBATE; + adcSingleRead(); + ADC->CCR &= ADC_CCR_VBATE; + return adcValues[TX_RTC] * 330 / 2048; +} + #if !defined(SIMU) uint16_t getAnalogValue(uint8_t index) { diff --git a/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp b/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp index 985b7b6f0..3f2bb898e 100644 --- a/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp +++ b/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp @@ -24,7 +24,7 @@ Fifo btTxFifo; Fifo btRxFifo; #if defined(PCBX7) || defined(PCBXLITE) -uint8_t btChipPresent = 0; +volatile uint8_t btChipPresent = 0; #endif enum BluetoothWriteState @@ -40,15 +40,11 @@ volatile uint8_t bluetoothWriteState = BLUETOOTH_WRITE_IDLE; void bluetoothInit(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - - USART_DeInit(BT_USART); - GPIO_InitStructure.GPIO_Pin = BT_EN_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(BT_EN_GPIO, &GPIO_InitStructure); #if defined(BT_BRTS_GPIO_PIN) @@ -63,32 +59,28 @@ void bluetoothInit(uint32_t baudrate) GPIO_Init(BT_BCTS_GPIO, &GPIO_InitStructure); #endif - GPIO_InitStructure.GPIO_Pin = BT_TX_GPIO_PIN|BT_RX_GPIO_PIN; + GPIO_PinAFConfig(BT_USART_GPIO, BT_TX_GPIO_PinSource, BT_GPIO_AF); + GPIO_PinAFConfig(BT_USART_GPIO, BT_RX_GPIO_PinSource, BT_GPIO_AF); + + GPIO_InitStructure.GPIO_Pin = BT_TX_GPIO_PIN | BT_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(BT_GPIO_TXRX, &GPIO_InitStructure); - - GPIO_PinAFConfig(BT_GPIO_TXRX, BT_TX_GPIO_PinSource, BT_GPIO_AF); - GPIO_PinAFConfig(BT_GPIO_TXRX, BT_RX_GPIO_PinSource, BT_GPIO_AF); + GPIO_Init(BT_USART_GPIO, &GPIO_InitStructure); USART_DeInit(BT_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_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(BT_USART, &USART_InitStructure); - USART_Cmd(BT_USART, ENABLE); - USART_ITConfig(BT_USART, USART_IT_RXNE, ENABLE); - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = BT_USART_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + USART_ITConfig(BT_USART, USART_IT_RXNE, ENABLE); + NVIC_SetPriority(BT_USART_IRQn, 6); + NVIC_EnableIRQ(BT_USART_IRQn); btRxFifo.clear(); btTxFifo.clear(); diff --git a/radio/src/targets/common/arm/stm32/cpu_id.cpp b/radio/src/targets/common/arm/stm32/cpu_id.cpp index ef8977d13..cd5a97a93 100644 --- a/radio/src/targets/common/arm/stm32/cpu_id.cpp +++ b/radio/src/targets/common/arm/stm32/cpu_id.cpp @@ -20,13 +20,14 @@ #include "opentx.h" +#if defined(SIMU) +const uint32_t cpu_uid[3] = { 0x12345678, 0x55AA55AA, 0x87654321}; +#else +const uint32_t * cpu_uid = (uint32_t *)0x1FFF7A10; +#endif + void getCPUUniqueID(char * s) { -#if defined(SIMU) - uint32_t cpu_uid[3] = { 0x12345678, 0x55AA55AA, 0x87654321}; -#else - uint32_t * cpu_uid = (uint32_t *)0x1FFF7A10; -#endif char * tmp = strAppendUnsigned(s, cpu_uid[0], 8, 16); *tmp = ' '; tmp = strAppendUnsigned(tmp+1, cpu_uid[1], 8, 16); diff --git a/radio/src/targets/common/arm/stm32/cpu_id.h b/radio/src/targets/common/arm/stm32/cpu_id.h new file mode 100644 index 000000000..eb95f8b3b --- /dev/null +++ b/radio/src/targets/common/arm/stm32/cpu_id.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#include + +void getCPUUniqueID(char * s); + +#define LEN_CPU_UID (3*8+2) + +#if defined(SIMU) +extern const uint32_t cpu_uid[3]; +#else +extern const uint32_t * cpu_uid; +#endif \ No newline at end of file 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 a930fd227..0f459d81d 100755 --- a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp @@ -20,43 +20,31 @@ #include "opentx.h" +ModuleFifo intmoduleFifo; + void intmoduleStop() { - INTERNAL_MODULE_OFF(); - - NVIC_DisableIRQ(INTMODULE_TIMER_IRQn); + GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN); INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; - INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; -} - -void intmoduleNoneStart() -{ - INTERNAL_MODULE_OFF(); GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN; + GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(INTMODULE_TX_GPIO, &GPIO_InitStructure); - GPIO_SetBits(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PIN); // Set high + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(INTMODULE_GPIO, &GPIO_InitStructure); - INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - INTMODULE_TIMER->ARR = 36000; // 18mS - INTMODULE_TIMER->CCR2 = 32000; // Update time - INTMODULE_TIMER->EGR = 1; // Restart - 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); + GPIO_ResetBits(INTMODULE_GPIO, INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN); } void intmodulePxxStart() +{ + intmoduleSerialStart(INTMODULE_PXX_BAUDRATE, false); +} + +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable) { INTERNAL_MODULE_ON(); @@ -67,97 +55,94 @@ void intmodulePxxStart() NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - // TX Pin - GPIO_PinAFConfig(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PinSource, INTMODULE_TX_GPIO_AF); + GPIO_PinAFConfig(INTMODULE_GPIO, INTMODULE_GPIO_PinSource_TX, INTMODULE_GPIO_AF); + GPIO_PinAFConfig(INTMODULE_GPIO, INTMODULE_GPIO_PinSource_RX, INTMODULE_GPIO_AF); GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN; + GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(INTMODULE_TX_GPIO, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(INTMODULE_GPIO, &GPIO_InitStructure); - // RX Pin - GPIO_PinAFConfig(INTMODULE_RX_GPIO, INTMODULE_RX_GPIO_PinSource, INTMODULE_TX_GPIO_AF); - GPIO_InitStructure.GPIO_Pin = INTMODULE_RX_GPIO_PIN; - GPIO_Init(INTMODULE_RX_GPIO, &GPIO_InitStructure); - - // UART config USART_DeInit(INTMODULE_USART); USART_InitTypeDef USART_InitStructure; - USART_InitStructure.USART_BaudRate = INTMODULE_USART_PXX_BAUDRATE; + 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_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(INTMODULE_USART, &USART_InitStructure); USART_Cmd(INTMODULE_USART, ENABLE); - // Timer - INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - INTMODULE_TIMER->ARR = PXX_PERIOD_HALF_US; - INTMODULE_TIMER->CCR2 = PXX_PERIOD_HALF_US - 2000; // Update time - 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); + if (rxEnable) { + intmoduleFifo.clear(); + USART_ITConfig(INTMODULE_USART, USART_IT_RXNE, ENABLE); + NVIC_SetPriority(INTMODULE_USART_IRQn, 6); + NVIC_EnableIRQ(INTMODULE_USART_IRQn); + } } -extern "C" void INTMODULE_DMA_STREAM_IRQHandler(void) +#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +extern "C" void INTMODULE_USART_IRQHandler(void) { - DEBUG_INTERRUPT(INT_DMA2S7); - if (DMA_GetITStatus(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC)) { - // TODO we could send the 8 next channels here (when needed) - DMA_ClearITPendingBit(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC); + uint32_t status = INTMODULE_USART->SR; + + while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { + uint8_t data = INTMODULE_USART->DR; + if (status & USART_FLAG_ERRORS) { + intmoduleFifo.errors++; + } + else { + hardwareOptions.pxx2Enabled = true; + intmoduleFifo.push(data); + } + status = INTMODULE_USART->SR; } } +void intmoduleSendBuffer(const uint8_t * data, uint8_t size) +{ + if (size == 0) + return; + + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(INTMODULE_DMA_STREAM); + DMA_InitStructure.DMA_Channel = INTMODULE_DMA_CHANNEL; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&INTMODULE_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(data); + DMA_InitStructure.DMA_BufferSize = size; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(INTMODULE_DMA_STREAM, &DMA_InitStructure); + DMA_Cmd(INTMODULE_DMA_STREAM, ENABLE); + USART_DMACmd(INTMODULE_USART, USART_DMAReq_Tx, ENABLE); +} + void intmoduleSendNextFrame() { - if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) { - DMA_InitTypeDef DMA_InitStructure; - DMA_DeInit(INTMODULE_DMA_STREAM); - DMA_InitStructure.DMA_Channel = INTMODULE_DMA_CHANNEL; - DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&INTMODULE_USART->DR); - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].pxx_uart.getData()); - DMA_InitStructure.DMA_BufferSize = modulePulsesData[INTERNAL_MODULE].pxx_uart.getSize(); - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(INTMODULE_DMA_STREAM, &DMA_InitStructure); + switch(moduleSettings[INTERNAL_MODULE].protocol) { +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + intmoduleSendBuffer(intmodulePulsesData.pxx2.getData(), intmodulePulsesData.pxx2.getSize()); + break; +#endif - DMA_Cmd(INTMODULE_DMA_STREAM, ENABLE); - USART_DMACmd(INTMODULE_USART, USART_DMAReq_Tx, ENABLE); +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + intmoduleSendBuffer(intmodulePulsesData.pxx_uart.getData(), intmodulePulsesData.pxx_uart.getSize()); + break; +#endif } } - -extern "C" void INTMODULE_TIMER_IRQHandler() -{ - DEBUG_INTERRUPT(INT_TIM1CC); - DEBUG_TIMER_SAMPLE(debugTimerIntPulses); - DEBUG_TIMER_START(debugTimerIntPulsesDuration); - - INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag - setupPulses(INTERNAL_MODULE); - intmoduleSendNextFrame(); - - DEBUG_TIMER_STOP(debugTimerIntPulsesDuration); -} diff --git a/radio/src/targets/common/arm/stm32/lsm6ds3_driver.cpp b/radio/src/targets/common/arm/stm32/lsm6ds3_driver.cpp new file mode 100644 index 000000000..8b8699b41 --- /dev/null +++ b/radio/src/targets/common/arm/stm32/lsm6ds3_driver.cpp @@ -0,0 +1,375 @@ +/* + * 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. + */ + +#include "opentx.h" + +//#define ACC_LSB_VALUE 0.000488 // 0.488 mg/LSB +//#define GYRO_LSB_VALUE 0.07 // 70mDPS in 2000 deg/second + +/* COMMON VALUES FOR ACCEL-GYRO SENSORS */ +#define LSM6DS3_WHO_AM_I 0x0f +#define LSM6DS3_WHO_AM_I_DEF 0x69 +#define LSM6DS3_AXIS_EN_MASK 0x38 +#define LSM6DS3_INT1_CTRL_ADDR 0x0d +#define LSM6DS3_INT2_CTRL_ADDR 0x0e +#define LSM6DS3_INT1_FULL 0x20 +#define LSM6DS3_INT1_FTH 0x08 +#define LSM6DS3_MD1_ADDR 0x5e +#define LSM6DS3_ODR_LIST_NUM 5 +#define LSM6DS3_ODR_POWER_OFF_VAL 0x00 +#define LSM6DS3_ODR_26HZ_VAL 0x02 +#define LSM6DS3_ODR_52HZ_VAL 0x03 +#define LSM6DS3_ODR_104HZ_VAL 0x04 +#define LSM6DS3_ODR_208HZ_VAL 0x05 +#define LSM6DS3_ODR_416HZ_VAL 0x06 +#define LSM6DS3_FS_LIST_NUM 4 +#define LSM6DS3_BDU_ADDR 0x12 +#define LSM6DS3_BDU_MASK 0x40 +#define LSM6DS3_EN_BIT 0x01 +#define LSM6DS3_DIS_BIT 0x00 +#define LSM6DS3_FUNC_EN_ADDR 0x19 +#define LSM6DS3_FUNC_EN_MASK 0x04 +#define LSM6DS3_FUNC_CFG_ACCESS_ADDR 0x01 +#define LSM6DS3_FUNC_CFG_ACCESS_MASK 0x01 +#define LSM6DS3_FUNC_CFG_ACCESS_MASK2 0x04 +#define LSM6DS3_FUNC_CFG_REG2_MASK 0x80 +#define LSM6DS3_FUNC_CFG_START1_ADDR 0x62 +#define LSM6DS3_FUNC_CFG_START2_ADDR 0x63 +#define LSM6DS3_SELFTEST_ADDR 0x14 +#define LSM6DS3_SELFTEST_ACCEL_MASK 0x03 +#define LSM6DS3_SELFTEST_GYRO_MASK 0x0c +#define LSM6DS3_SELF_TEST_DISABLED_VAL 0x00 +#define LSM6DS3_SELF_TEST_POS_SIGN_VAL 0x01 +#define LSM6DS3_SELF_TEST_NEG_ACCEL_SIGN_VAL 0x02 +#define LSM6DS3_SELF_TEST_NEG_GYRO_SIGN_VAL 0x03 +#define LSM6DS3_LIR_ADDR 0x58 +#define LSM6DS3_LIR_MASK 0x01 +#define LSM6DS3_TIMER_EN_ADDR 0x58 +#define LSM6DS3_TIMER_EN_MASK 0x80 +#define LSM6DS3_PEDOMETER_EN_ADDR 0x58 +#define LSM6DS3_PEDOMETER_EN_MASK 0x40 +#define LSM6DS3_INT2_ON_INT1_ADDR 0x13 +#define LSM6DS3_INT2_ON_INT1_MASK 0x20 +#define LSM6DS3_MIN_DURATION_MS 1638 +#define LSM6DS3_ROUNDING_ADDR 0x16 +#define LSM6DS3_ROUNDING_MASK 0x04 +#define LSM6DS3_FIFO_MODE_ADDR 0x0a +#define LSM6DS3_FIFO_MODE_MASK 0x07 +#define LSM6DS3_FIFO_MODE_BYPASS 0x00 +#define LSM6DS3_FIFO_MODE_CONTINUOS 0x06 +#define LSM6DS3_FIFO_THRESHOLD_IRQ_MASK 0x08 +#define LSM6DS3_FIFO_ODR_ADDR 0x0a +#define LSM6DS3_FIFO_ODR_MASK 0x78 +#define LSM6DS3_FIFO_ODR_MAX 0x07 +#define LSM6DS3_FIFO_ODR_MAX_HZ 800 +#define LSM6DS3_FIFO_ODR_OFF 0x00 +#define LSM6DS3_FIFO_CTRL3_ADDR 0x08 +#define LSM6DS3_FIFO_ACCEL_DECIMATOR_MASK 0x07 +#define LSM6DS3_FIFO_GYRO_DECIMATOR_MASK 0x38 +#define LSM6DS3_FIFO_CTRL4_ADDR 0x09 +#define LSM6DS3_FIFO_STEP_C_DECIMATOR_MASK 0x38 +#define LSM6DS3_FIFO_THR_L_ADDR 0x06 +#define LSM6DS3_FIFO_THR_H_ADDR 0x07 +#define LSM6DS3_FIFO_THR_H_MASK 0x0f +#define LSM6DS3_FIFO_THR_IRQ_MASK 0x08 +#define LSM6DS3_FIFO_PEDO_E_ADDR 0x07 +#define LSM6DS3_FIFO_PEDO_E_MASK 0x80 +#define LSM6DS3_FIFO_STEP_C_FREQ 25 + +/* CUSTOM VALUES FOR ACCEL SENSOR */ +#define LSM6DS3_ACCEL_ODR_ADDR 0x10 +#define LSM6DS3_ACCEL_ODR_MASK 0xf0 +#define LSM6DS3_ACCEL_FS_ADDR 0x10 +#define LSM6DS3_ACCEL_FS_MASK 0x0c +#define LSM6DS3_ACCEL_FS_2G_VAL 0x00 +#define LSM6DS3_ACCEL_FS_4G_VAL 0x02 +#define LSM6DS3_ACCEL_FS_8G_VAL 0x03 +#define LSM6DS3_ACCEL_FS_16G_VAL 0x01 +#define LSM6DS3_ACCEL_FS_2G_GAIN 61 +#define LSM6DS3_ACCEL_FS_4G_GAIN 122 +#define LSM6DS3_ACCEL_FS_8G_GAIN 244 +#define LSM6DS3_ACCEL_FS_16G_GAIN 488 +#define LSM6DS3_ACCEL_OUT_X_L_ADDR 0x28 +#define LSM6DS3_ACCEL_OUT_Y_L_ADDR 0x2a +#define LSM6DS3_ACCEL_OUT_Z_L_ADDR 0x2c +#define LSM6DS3_ACCEL_AXIS_EN_ADDR 0x18 +#define LSM6DS3_ACCEL_DRDY_IRQ_MASK 0x01 +#define LSM6DS3_ACCEL_STD 1 +#define LSM6DS3_ACCEL_STD_FROM_PD 2 + +/* CUSTOM VALUES FOR GYRO SENSOR */ +#define LSM6DS3_GYRO_ODR_ADDR 0x11 +#define LSM6DS3_GYRO_ODR_MASK 0xf0 +#define LSM6DS3_GYRO_FS_ADDR 0x11 +#define LSM6DS3_GYRO_FS_MASK 0x0c +#define LSM6DS3_GYRO_FS_245_VAL 0x00 +#define LSM6DS3_GYRO_FS_500_VAL 0x01 +#define LSM6DS3_GYRO_FS_1000_VAL 0x02 +#define LSM6DS3_GYRO_FS_2000_VAL 0x03 +#define LSM6DS3_GYRO_FS_245_GAIN 8750 +#define LSM6DS3_GYRO_FS_500_GAIN 17500 +#define LSM6DS3_GYRO_FS_1000_GAIN 35000 +#define LSM6DS3_GYRO_FS_2000_GAIN 70000 +#define LSM6DS3_GYRO_OUT_X_L_ADDR 0x22 +#define LSM6DS3_GYRO_OUT_Y_L_ADDR 0x24 +#define LSM6DS3_GYRO_OUT_Z_L_ADDR 0x26 +#define LSM6DS3_GYRO_AXIS_EN_ADDR 0x19 +#define LSM6DS3_GYRO_DRDY_IRQ_MASK 0x02 +#define LSM6DS3_GYRO_STD 6 +#define LSM6DS3_GYRO_STD_FROM_PD 2 + +#define LSM6DS3_OUT_XYZ_SIZE 8 + +/* CUSTOM VALUES FOR SIGNIFICANT MOTION SENSOR */ +#define LSM6DS3_SIGN_MOTION_EN_ADDR 0x19 +#define LSM6DS3_SIGN_MOTION_EN_MASK 0x01 +#define LSM6DS3_SIGN_MOTION_DRDY_IRQ_MASK 0x40 + +/* CUSTOM VALUES FOR STEP DETECTOR SENSOR */ +#define LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK 0x80 + +/* CUSTOM VALUES FOR STEP COUNTER SENSOR */ +#define LSM6DS3_STEP_COUNTER_DRDY_IRQ_MASK 0x80 +#define LSM6DS3_STEP_COUNTER_OUT_L_ADDR 0x4b +#define LSM6DS3_STEP_COUNTER_OUT_SIZE 2 +#define LSM6DS3_STEP_COUNTER_RES_ADDR 0x19 +#define LSM6DS3_STEP_COUNTER_RES_MASK 0x06 +#define LSM6DS3_STEP_COUNTER_RES_ALL_EN 0x03 +#define LSM6DS3_STEP_COUNTER_RES_FUNC_EN 0x02 +#define LSM6DS3_STEP_COUNTER_DURATION_ADDR 0x15 + +/* CUSTOM VALUES FOR TILT SENSOR */ +#define LSM6DS3_TILT_EN_ADDR 0x58 +#define LSM6DS3_TILT_EN_MASK 0x20 +#define LSM6DS3_TILT_DRDY_IRQ_MASK 0x02 + +#define LSM6DS3_ENABLE_AXIS 0x07 +#define LSM6DS3_FIFO_DIFF_L 0x3a +#define LSM6DS3_FIFO_DIFF_MASK 0x0fff +#define LSM6DS3_FIFO_DATA_OUT_L 0x3e +#define LSM6DS3_FIFO_ELEMENT_LEN_BYTE 6 +#define LSM6DS3_FIFO_BYTE_FOR_CHANNEL 2 +#define LSM6DS3_FIFO_DATA_OVR_2REGS 0x4000 +#define LSM6DS3_FIFO_DATA_OVR 0x40 + +#define LSM6DS3_SRC_FUNC_ADDR 0x53 +#define LSM6DS3_FIFO_DATA_AVL_ADDR 0x3b + +#define LSM6DS3_SRC_SIGN_MOTION_DATA_AVL 0x40 +#define LSM6DS3_SRC_STEP_DETECTOR_DATA_AVL 0x10 +#define LSM6DS3_SRC_TILT_DATA_AVL 0x20 +#define LSM6DS3_SRC_STEP_COUNTER_DATA_AVL 0x80 +#define LSM6DS3_FIFO_DATA_AVL 0x80 +#define LSM6DS3_RESET_ADDR 0x12 +#define LSM6DS3_RESET_MASK 0x01 + +#define LSM6DS3_ADDRESS 0xD6 +#define LSM6DSLTR_ID 0x6A + +static const char configure[][2] = + { + {LSM6DS3_ACCEL_AXIS_EN_ADDR, 0x38}, ///< xyz + {LSM6DS3_ACCEL_ODR_ADDR, (0x3 << 4) | (0x1 << 2) | (0x3 << 0)}, //ODR_52Hz|16G|BW_50Hz + {LSM6DS3_GYRO_AXIS_EN_ADDR, 0x38}, ///< xyz + {LSM6DS3_GYRO_ODR_ADDR, (3 << 4) | (3 << 2) | (0 << 0)}, ///< ODR_52Hz|2000dps| + {LSM6DS3_INT1_CTRL_ADDR, 0x3}, ///< GYRO_READY | ACCL_READY + {LSM6DS3_INT2_CTRL_ADDR, 0x3}, ///< GYRO_READY | ACCL_READY + }; + +volatile int lsm6ds3_state = 1; + +static void i2c2Init() +{ + I2C_DeInit(I2CX); + + I2C_InitTypeDef I2C_InitStructure; + I2C_InitStructure.I2C_ClockSpeed = I2CX_SPEED; + I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_Init(I2CX, &I2C_InitStructure); + I2C_Cmd(I2CX, ENABLE); + + GPIO_PinAFConfig(I2CX_SCL_GPIO, I2CX_SCL_GPIO_PinSource, I2CX_GPIO_AF); + GPIO_PinAFConfig(I2CX_SDA_GPIO, I2CX_SDA_GPIO_PinSource, I2CX_GPIO_AF); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = I2CX_SCL_GPIO_PIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(I2CX_SCL_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = I2CX_SDA_GPIO_PIN; + GPIO_Init(I2CX_SDA_GPIO, &GPIO_InitStructure); +} + +#define I2C_TIMEOUT_MAX 10000 +bool I2C2_WaitEvent(uint32_t event) +{ + uint32_t timeout = I2C_TIMEOUT_MAX; + while (!I2C_CheckEvent(I2CX, event)) { + if ((timeout--) == 0) return false; + } + return true; +} + +bool I2C2_WaitEventCleared(uint32_t event) +{ + uint32_t timeout = I2C_TIMEOUT_MAX; + while (I2C_CheckEvent(I2CX, event)) { + if ((timeout--) == 0) return false; + } + return true; +} + +int setGyroRegister(uint8_t address, uint8_t value) +{ + if (!I2C2_WaitEventCleared(I2C_FLAG_BUSY)) + return -1; + + I2C_GenerateSTART(I2CX, ENABLE); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) + return -1; + + I2C_Send7bitAddress(I2CX, LSM6DS3_ADDRESS, I2C_Direction_Transmitter); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + return -1; + + I2C_SendData(I2CX, address); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) // TODO TRANSMITTING + return -1; + + I2C_SendData(I2CX, value); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) + return -1; + + I2C_GenerateSTOP(I2CX, ENABLE); + + return 0; +} + +int readGyroRegister(uint8_t address) +{ + if (!I2C2_WaitEventCleared(I2C_FLAG_BUSY)) + return -1; + + I2C_GenerateSTART(I2CX, ENABLE); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) + return -1; + + I2C_Send7bitAddress(I2CX, LSM6DS3_ADDRESS, I2C_Direction_Transmitter); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + return -1; + + I2C_SendData(I2CX, address); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) + return -1; + + I2C_GenerateSTART(I2CX, ENABLE); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) + return -1; + + I2C_Send7bitAddress(I2CX, LSM6DS3_ADDRESS, I2C_Direction_Receiver); + + I2C_AcknowledgeConfig(I2CX, DISABLE); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED)) + return -1; + + uint8_t value = I2C_ReceiveData(I2CX); + + I2C_GenerateSTOP(I2CX, ENABLE); + + return value; +} + +int gyroInit() +{ + i2c2Init(); + + uint8_t id = readGyroRegister(LSM6DS3_WHO_AM_I); + if (id != LSM6DSLTR_ID) { + return -1; + } + + TRACE("OK"); + + setGyroRegister(0x12, 0x05); + delay_ms(1); + setGyroRegister(0x12, 0x04); + delay_ms(1); + + TRACE("OK2"); + + for (uint8_t i = 0; i < DIM(configure); i++) { + setGyroRegister(configure[i][0], configure[i][1]); + } + + TRACE("OK4"); + + return 0; +} + +#if 0 +int gyroRead(void *buffer, int len, OFFSET offset1) +{ + char t_char[10]; + short t_short[7]; + + short *p_short; + I2C_transfer_block i2c_block[2]; + + xSemaphoreTake(lsm6ds3_sema, portMAX_DELAY); + + t_char[0] = LSM6DS3_GYRO_OUT_X_L_ADDR; + + i2c_block[0].addr = LSM6DS3_ADDRESS; + i2c_block[0].rw = I2C_WRITE; + i2c_block[0].stop_mode = I2C_WRITE_BYPASS_STOP; + i2c_block[0].len = 1; + i2c_block[0].buf = t_char; + + i2c_block[1].addr = LSM6DS3_ADDRESS; + i2c_block[1].rw = I2C_READ; + i2c_block[1].stop_mode = I2C_WRITE_APPEND_STOP; + + i2c_block[1].len = len; + i2c_block[1].buf = (char *) t_short; + + i2c_dma_transfer(i2c_block, 2); + + { + p_short = (short *) buffer; + *p_short++ = t_short[0]; + *p_short++ = -t_short[1]; + *p_short++ = t_short[2]; + + *p_short++ = -t_short[3]; + *p_short++ = t_short[4]; + *p_short++ = -t_short[5]; + } + + return len; +} + +#endif \ No newline at end of file diff --git a/radio/src/targets/common/arm/stm32/serial2_driver.cpp b/radio/src/targets/common/arm/stm32/serial2_driver.cpp index 049f09374..cb39d4173 100644 --- a/radio/src/targets/common/arm/stm32/serial2_driver.cpp +++ b/radio/src/targets/common/arm/stm32/serial2_driver.cpp @@ -97,7 +97,7 @@ void serial2Init(unsigned int mode, unsigned int protocol) break; #endif case UART_MODE_TELEMETRY: - if (protocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { uart3Setup(FRSKY_D_BAUDRATE, true); } break; diff --git a/radio/src/targets/common/arm/stm32/sticks_pwm_driver.cpp b/radio/src/targets/common/arm/stm32/sticks_pwm_driver.cpp index a3c065963..e219f5521 100644 --- a/radio/src/targets/common/arm/stm32/sticks_pwm_driver.cpp +++ b/radio/src/targets/common/arm/stm32/sticks_pwm_driver.cpp @@ -20,7 +20,6 @@ #include "opentx.h" -bool sticks_pwm_disabled = false; volatile uint32_t pwm_interrupt_count; volatile uint16_t timer_capture_values[NUM_PWMSTICKS]; diff --git a/radio/src/targets/common/arm/stm32/usb_driver.cpp b/radio/src/targets/common/arm/stm32/usb_driver.cpp index 7b4aaf530..e47774623 100644 --- a/radio/src/targets/common/arm/stm32/usb_driver.cpp +++ b/radio/src/targets/common/arm/stm32/usb_driver.cpp @@ -44,7 +44,7 @@ int getSelectedUsbMode() void setSelectedUsbMode(int mode) { - selectedUsbMode = usbMode (mode); + selectedUsbMode = usbMode(mode); } int usbPlugged() diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 28c7abcde..ef12c59b4 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -146,6 +146,7 @@ add_definitions(-DBLUETOOTH) set(SRC ${SRC} bluetooth.cpp + io/frsky_device_firmware_update.cpp ) set(STM32LIB_SRC diff --git a/radio/src/targets/horus/adc_driver.cpp b/radio/src/targets/horus/adc_driver.cpp index bfd6f63f4..248bd85ef 100644 --- a/radio/src/targets/horus/adc_driver.cpp +++ b/radio/src/targets/horus/adc_driver.cpp @@ -20,7 +20,7 @@ #include "opentx.h" -uint16_t adcValues[NUM_ANALOGS] __DMA; +uint16_t adcValues[NUM_ANALOGS + 1/*RTC*/] __DMA; #define ADC_CS_HIGH() (ADC_SPI_GPIO->BSRRL = ADC_SPI_PIN_CS) #define ADC_CS_LOW() (ADC_SPI_GPIO->BSRRH = ADC_SPI_PIN_CS) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index 02f54c5fc..0ac2357a5 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -29,6 +29,8 @@ extern "C" { } #endif +HardwareOptions hardwareOptions; + void watchdogInit(unsigned int duration) { IWDG->KR = 0x5555; // Unlock registers @@ -178,9 +180,6 @@ void boardInit() pwrInit(); delaysInit(); - // FrSky removed the volume chip in latest board, that's why it doesn't answer! - // i2cInit(); - #if defined(DEBUG) serial2Init(0, 0); // default serial mode (None if DEBUG not defined) #endif @@ -190,9 +189,14 @@ void boardInit() TRACE("\nHorus board started :)"); TRACE("RCC->CSR = %08x", RCC->CSR); +#if defined(PXX2) + #warning "PXX2 probe is not implemented" + hardwareOptions.pxx2Enabled = true; +#endif + audioInit(); - // we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access) + // we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access) // and this section is un-initialized memset(&g_FATFS_Obj, 0, sizeof(g_FATFS_Obj)); @@ -202,7 +206,7 @@ void boardInit() sticksPwmInit(); delay_ms(20); if (pwm_interrupt_count < 32) { - sticks_pwm_disabled = true; + hardwareOptions.sticksPwmDisabled = true; } #endif @@ -252,7 +256,7 @@ uint8_t currentTrainerMode = 0xff; void checkTrainerSettings() { - uint8_t requiredTrainerMode = g_model.trainerMode; + uint8_t requiredTrainerMode = g_model.trainerData.mode; if (requiredTrainerMode != currentTrainerMode) { switch (currentTrainerMode) { case TRAINER_MODE_MASTER_TRAINER_JACK: diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index d14f2f706..03fd11070 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -21,8 +21,8 @@ #ifndef _BOARD_HORUS_H_ #define _BOARD_HORUS_H_ -#include "stddef.h" -#include "stdbool.h" +#include "../definitions.h" +#include "cpu_id.h" #if defined(__cplusplus) && !defined(SIMU) extern "C" { @@ -97,7 +97,7 @@ extern "C" { extern uint16_t sessionTimer; -#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE) +#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) #if defined(PCBX10) #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET) @@ -105,6 +105,14 @@ extern uint16_t sessionTimer; #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET) #endif +#if defined(PCBX10) + #define NUM_SLIDERS 2 + #define NUM_PWMSTICKS 4 +#else + #define NUM_SLIDERS 4 + #define NUM_PWMSTICKS 0 +#endif + // Board driver void boardInit(void); void boardOff(void); @@ -131,9 +139,15 @@ void delay_ms(uint32_t ms); #define IS_FIRMWARE_COMPATIBLE_WITH_BOARD() (!IS_HORUS_PROD()) #endif -// CPU Unique ID -#define LEN_CPU_UID (3*8+2) -void getCPUUniqueID(char * s); +// Hardware options +PACK(typedef struct { +#if NUM_PWMSTICKS > 0 + uint8_t sticksPwmDisabled:1; +#endif + uint8_t pxx2Enabled:1; +}) HardwareOptions; + +extern HardwareOptions hardwareOptions; // SD driver #define BLOCK_SIZE 512 /* Block Size in Bytes */ @@ -180,23 +194,44 @@ void SDRAM_Init(void); // Pulses driver #define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) -#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) + +#if defined(INTMODULE_USART) + #define INTERNAL_MODULE_OFF() intmoduleStop() +#else + #define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) +#endif + #define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) -#define IS_UART_MODULE(port) (port == INTERNAL_MODULE) -void init_no_pulses(uint32_t port); -void disable_no_pulses(uint32_t port); -void init_ppm(uint32_t module_index); -void disable_ppm(uint32_t module_index); -void init_pxx(uint32_t module_index); -void disable_pxx(uint32_t module_index); -void init_serial(uint32_t module_index, uint32_t baudrate, uint32_t period_half_us); -void disable_serial(uint32_t module_index); -void init_module_timer( uint32_t module_index, uint32_t period, uint8_t state); -void disable_module_timer( uint32_t module_index); +#if !defined(PXX2) + #define IS_PXX2_INTERNAL_ENABLED() (false) + #define IS_PXX1_INTERNAL_ENABLED() (true) +#elif !defined(PXX1) + #define IS_PXX2_INTERNAL_ENABLED() (true) + #define IS_PXX1_INTERNAL_ENABLED() (false) +#else + // TODO #define PXX2_PROBE + // TODO #define IS_PXX2_INTERNAL_ENABLED() (hardwareOptions.pxx2Enabled) + #define IS_PXX2_INTERNAL_ENABLED() (true) + #define IS_PXX1_INTERNAL_ENABLED() (true) +#endif + +void init_ppm(uint8_t module); +void disable_ppm(uint8_t module); +void init_pxx1_pulses(uint8_t module); +void disable_pxx1_pulses(uint8_t module); +void init_pxx2(uint8_t module); +void disable_pxx2(uint8_t module); +void init_serial(uint8_t module, uint32_t baudrate, uint32_t period_half_us); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); +void disable_serial(uint8_t module); +void intmoduleStop(); +void intmoduleSendBuffer(const uint8_t * data, uint8_t size); +void intmoduleSendNextFrame(); +void extmoduleSendNextFrame(); // Trainer driver void init_trainer_ppm(void); @@ -280,6 +315,7 @@ enum EnumSwitchesPositions SW_SH0, SW_SH1, SW_SH2, + NUM_SWITCHES_POSITIONS }; void keysInit(void); uint8_t keyState(uint8_t index); @@ -334,13 +370,6 @@ void watchdogInit(unsigned int duration); // ADC driver #define NUM_POTS 3 #define NUM_XPOTS NUM_POTS -#if defined(PCBX10) - #define NUM_SLIDERS 2 - #define NUM_PWMSTICKS 4 -#else - #define NUM_SLIDERS 4 - #define NUM_PWMSTICKS 0 -#endif enum Analogs { STICK1, STICK2, @@ -365,9 +394,10 @@ enum Analogs { #endif SLIDER_LAST = SLIDER_FIRST + NUM_SLIDERS - 1, TX_VOLTAGE, - MOUSE1, + MOUSE1, // TODO why after voltage? MOUSE2, - NUM_ANALOGS + NUM_ANALOGS, + TX_RTC = NUM_ANALOGS }; enum CalibratedAnalogs { @@ -394,9 +424,10 @@ enum CalibratedAnalogs { #define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST) #define IS_SLIDER(x) ((x)>=SLIDER_FIRST && (x)<=SLIDER_LAST) -extern uint16_t adcValues[NUM_ANALOGS]; +extern uint16_t adcValues[NUM_ANALOGS + 1/*RTC*/]; void adcInit(void); void adcRead(void); +uint16_t getRTCBattVoltage(); uint16_t getAnalogValue(uint8_t index); #define NUM_MOUSE_ANALOGS 2 #if defined(PCBX10) @@ -406,8 +437,7 @@ uint16_t getAnalogValue(uint8_t index); #endif #if NUM_PWMSTICKS > 0 -extern bool sticks_pwm_disabled; -#define STICKS_PWM_ENABLED() (sticks_pwm_disabled == false) +#define STICKS_PWM_ENABLED() (!hardwareOptions.sticksPwmDisabled) void sticksPwmInit(void); void sticksPwmRead(uint16_t * values); extern volatile uint32_t pwm_interrupt_count; diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 724c16837..4fb25ab08 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -20,8 +20,6 @@ #include "opentx.h" -void extmoduleSendNextFrame(); - void extmoduleStop() { EXTERNAL_MODULE_OFF(); @@ -34,38 +32,6 @@ void extmoduleStop() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; } -void extmoduleTimerStart(uint32_t period, uint8_t state) -{ - if (state) - EXTERNAL_MODULE_ON(); - else - EXTERNAL_MODULE_OFF(); - - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, 0); - - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); - GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); // Set high - - EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = (2000 * period); - EXTMODULE_TIMER->CCR2 = (2000 * period) - 1000; - EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - - NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); -} - - void extmodulePpmStart() { EXTERNAL_MODULE_ON(); @@ -102,8 +68,8 @@ void extmodulePpmStart() EXTMODULE_TIMER->DIER = TIM_DIER_UDE; // Update DMA request EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer #else - EXTMODULE_TIMER->CCR1 = GET_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); + EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; // Reloads register values now EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Update DMA request @@ -165,6 +131,11 @@ void extmodulePxxStart() NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); } +void extmodulePxx2Start() +{ + // TODO just enable the S.PORT line (or let telemetry init do it) +} + #if defined(DSM2) void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) { @@ -213,29 +184,56 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) } #endif +#if defined(EXTMODULE_USART) +void extmoduleSendBuffer(const uint8_t * data, uint8_t size) +{ + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(EXTMODULE_DMA_STREAM); + DMA_InitStructure.DMA_Channel = EXTMODULE_DMA_CHANNEL; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(data); + DMA_InitStructure.DMA_BufferSize = size; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(EXTMODULE_DMA_STREAM, &DMA_InitStructure); + DMA_Cmd(EXTMODULE_DMA_STREAM, ENABLE); + USART_DMACmd(EXTMODULE_USART, USART_DMAReq_Tx, ENABLE); +} +#endif + void extmoduleSendNextFrame() { - if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) { + if (moduleSettings[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PPM) { #if defined(PCBX10) || PCBREV >= 13 - EXTMODULE_TIMER->CCR3 = GET_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); - EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].ppm.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; #else - EXTMODULE_TIMER->CCR1 = GET_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); - EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].ppm.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; #endif EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].ppm.pulses); - EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].ppm.ptr - modulePulsesData[EXTERNAL_MODULE].ppm.pulses; + EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses); + EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.ppm.ptr - extmodulePulsesData.ppm.pulses; EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA } - else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) { - EXTMODULE_TIMER->CCR2 = modulePulsesData[EXTERNAL_MODULE].pxx.getLast() - 4000; // 2mS in advance +#if defined(PXX1) + else if (moduleSettings[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PXX1_PULSES) { + EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA #if defined(PCBX10) || PCBREV >= 13 EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; @@ -243,25 +241,34 @@ void extmoduleSendNextFrame() EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; #endif EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.getData()); - EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.getSize(); + EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); + EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize(); EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA } - else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { - EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance + else if (moduleSettings[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PXX1_SERIAL) { + #warning "Take it from 2.2" + } +#endif +#if defined(PXX2) + else if (moduleSettings[EXTERNAL_MODULE].protocol == PROTOCOL_CHANNELS_PXX2) { + // TODO + } +#endif + else if (IS_DSM2_PROTOCOL(moduleSettings[EXTERNAL_MODULE].protocol) || IS_MULTIMODULE_PROTOCOL(moduleSettings[EXTERNAL_MODULE].protocol) || IS_SBUS_PROTOCOL(moduleSettings[EXTERNAL_MODULE].protocol)) { + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA #if defined(PCBX10) || PCBREV >= 13 EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + if (IS_SBUS_PROTOCOL(moduleSettings[EXTERNAL_MODULE].protocol)) EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed #else EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + if (IS_SBUS_PROTOCOL(moduleSettings[EXTERNAL_MODULE].protocol)) EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed #endif EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); - EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); + EXTMODULE_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses; EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA } else { @@ -284,6 +291,6 @@ extern "C" void EXTMODULE_TIMER_IRQHandler() { EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - setupPulses(EXTERNAL_MODULE); - extmoduleSendNextFrame(); + if (setupPulses(EXTERNAL_MODULE)) + extmoduleSendNextFrame(); } diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index c5f9ff11e..64eca001d 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -197,6 +197,7 @@ #define ADC_DMA DMA2 #define ADC_DMA_Stream DMA2_Stream0 #define ADC_SAMPTIME 3 + #define ADC_CHANNEL_RTC 0 // TODO later ... ADC1_IN18 #elif defined(PCBX10) #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA2) #define ADC_RCC_APB1Periph (RCC_APB1Periph_TIM5) @@ -234,6 +235,7 @@ #define ADC_CHANNEL_BATT ADC_Channel_5 // ADC3_IN5 #define ADC_CHANNEL_EXT1 ADC_Channel_6 // ADC3_IN6 #define ADC_CHANNEL_EXT2 ADC_Channel_7 // ADC3_IN7 + #define ADC_CHANNEL_RTC 0 // TODO later ... ADC1_IN18 #define ADC_MAIN ADC3 #define ADC_SAMPTIME 3 #define ADC_DMA DMA2 @@ -249,8 +251,6 @@ #define PWR_SWITCH_GPIO_REG PWR_GPIO->IDR #define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 #define PWR_ON_GPIO_PIN GPIO_Pin_1 // PJ.01 -#define PWR_ON_GPIO_MODER GPIO_MODER_MODER1 -#define PWR_ON_GPIO_MODER_OUT GPIO_MODER_MODER1_0 // S.Port update connector #define SPORT_MAX_BAUDRATE 250000 // < 400000 @@ -512,17 +512,17 @@ #endif // Internal Module +#define HARDWARE_INTERNAL_MODULE #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 -#define INTMODULE_TX_GPIO GPIOB +#define INTMODULE_GPIO GPIOB #define INTMODULE_TX_GPIO_PIN GPIO_Pin_6 // PB.06 -#define INTMODULE_RX_GPIO GPIOB #define INTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PB.07 -#define INTMODULE_TX_GPIO_PinSource GPIO_PinSource6 -#define INTMODULE_RX_GPIO_PinSource GPIO_PinSource7 +#define INTMODULE_GPIO_PinSource_TX GPIO_PinSource6 +#define INTMODULE_GPIO_PinSource_RX GPIO_PinSource7 #define INTMODULE_USART USART1 -#define INTMODULE_TX_GPIO_AF GPIO_AF_USART1 +#define INTMODULE_GPIO_AF GPIO_AF_USART1 #define INTMODULE_USART_IRQn USART1_IRQn #define INTMODULE_DMA_STREAM DMA2_Stream7 #define INTMODULE_DMA_STREAM_IRQ DMA2_Stream7_IRQn @@ -634,7 +634,7 @@ #define BT_USART USART6 #define BT_GPIO_AF GPIO_AF_USART6 #define BT_USART_IRQn USART6_IRQn -#define BT_GPIO_TXRX GPIOG +#define BT_USART_GPIO GPIOG #define BT_TX_GPIO_PIN GPIO_Pin_14 // PG.14 #define BT_RX_GPIO_PIN GPIO_Pin_9 // PG.09 #define BT_TX_GPIO_PinSource GPIO_PinSource14 diff --git a/radio/src/targets/horus/pulses_driver.cpp b/radio/src/targets/horus/pulses_driver.cpp index 97305df0b..57fca8889 100644 --- a/radio/src/targets/horus/pulses_driver.cpp +++ b/radio/src/targets/horus/pulses_driver.cpp @@ -20,90 +20,76 @@ #include "opentx.h" -void intmoduleStop(void); -void extmoduleStop(void); +void intmoduleStop(); +void intmodulePxxStart(); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); -void intmoduleNoneStart(void); -void intmodulePxxStart(void); - -void extmoduleTimerStart(uint32_t period, uint8_t state); -void extmodulePpmStart(void); -void extmodulePxxStart(void); +void extmoduleStop(); +void extmodulePpmStart(); +void extmodulePxxStart(); +void extmodulePxx2Start(); void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us); -void init_no_pulses(uint32_t port) + +void init_ppm(uint8_t module) { - if (port == INTERNAL_MODULE) - intmoduleNoneStart(); - else - extmoduleTimerStart(18, false); + if (module == EXTERNAL_MODULE) { + extmodulePpmStart(); + } } -void disable_no_pulses(uint32_t port) +void disable_ppm(uint8_t module) { - if (port == INTERNAL_MODULE) + if (module == EXTERNAL_MODULE) { + extmoduleStop(); + } +} + +void init_pxx2(uint8_t module) +{ + if (module == INTERNAL_MODULE) + intmoduleSerialStart(INTMODULE_PXX_BAUDRATE, true); + else + extmodulePxx2Start(); +} + +void disable_pxx2(uint8_t module) +{ + if (module == INTERNAL_MODULE) intmoduleStop(); else extmoduleStop(); } -void init_ppm(uint32_t port) +void init_pxx1_pulses(uint8_t module) { - if (port == EXTERNAL_MODULE) { - extmodulePpmStart(); - } -} - -void disable_ppm(uint32_t port) -{ - if (port == EXTERNAL_MODULE) { - extmoduleStop(); - } -} - -void init_pxx(uint32_t port) -{ - if (port == INTERNAL_MODULE) + if (module == INTERNAL_MODULE) intmodulePxxStart(); else extmodulePxxStart(); } -void disable_pxx(uint32_t port) +void disable_pxx1_pulses(uint8_t module) { - if (port == INTERNAL_MODULE) + if (module == INTERNAL_MODULE) intmoduleStop(); else extmoduleStop(); } #if defined(DSM2) -void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us) +void init_serial(uint8_t module, uint32_t baudrate, uint32_t period_half_us) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmoduleSerialStart(baudrate, period_half_us); } } -void disable_serial(uint32_t port) +void disable_serial(uint8_t module) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmoduleStop(); } } #endif -void init_module_timer(uint32_t port, uint32_t period, uint8_t state) -{ - if (port == EXTERNAL_MODULE) { - extmoduleTimerStart(period, state); - } -} - -void disable_module_timer(uint32_t port) -{ - if (port == EXTERNAL_MODULE) { - extmoduleStop(); - } -} - diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index 8541c0742..21e9f6c5a 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -175,9 +175,8 @@ extern "C" void TELEMETRY_DMA_TX_IRQHandler(void) if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) { DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC); TELEMETRY_USART->CR1 |= USART_CR1_TCIE; - if (telemetryProtocol == PROTOCOL_FRSKY_SPORT) { - outputTelemetryBufferSize = 0; - outputTelemetryBufferTrigger = 0x7E; + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) { + outputTelemetryBuffer.reset(); } } } @@ -205,10 +204,10 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) else { telemetryNoDMAFifo.push(data); #if defined(LUA) - if (telemetryProtocol == PROTOCOL_FRSKY_SPORT) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) { static uint8_t prevdata; - if (prevdata == 0x7E && outputTelemetryBufferSize > 0 && data == outputTelemetryBufferTrigger) { - sportSendBuffer(outputTelemetryBuffer, outputTelemetryBufferSize); + if (prevdata == 0x7E && outputTelemetryBuffer.size > 0 && data == outputTelemetryBuffer.trigger && outputTelemetryBuffer.destination == SPORT_MODULE) { + sportSendBuffer(outputTelemetryBuffer.data, outputTelemetryBuffer.size); } prevdata = data; } diff --git a/radio/src/targets/horus/trainer_driver.cpp b/radio/src/targets/horus/trainer_driver.cpp index d05648b47..d5b34cc1e 100644 --- a/radio/src/targets/horus/trainer_driver.cpp +++ b/radio/src/targets/horus/trainer_driver.cpp @@ -37,8 +37,8 @@ void init_trainer_ppm() TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS TRAINER_TIMER->ARR = 45000; - TRAINER_TIMER->CCR2 = GET_PPM_DELAY(TRAINER_MODULE)*2; - TRAINER_TIMER->CCER = TIM_CCER_CC2E | (g_model.moduleData[TRAINER_MODULE].ppm.pulsePol ? 0 : TIM_CCER_CC2P); + TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2; + TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P); TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_0; // Force O/P high TRAINER_TIMER->BDTR = TIM_BDTR_MOE; TRAINER_TIMER->EGR = 1; @@ -100,8 +100,8 @@ void stop_trainer_capture() void trainerSendNextFrame() { - TRAINER_TIMER->CCR2 = GET_PPM_DELAY(TRAINER_MODULE)*2; - TRAINER_TIMER->CCER = TIM_CCER_CC2E | (g_model.moduleData[TRAINER_MODULE].ppm.pulsePol ? 0 : TIM_CCER_CC2P); + TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2; + TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P); TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index dedbaec25..cf35464b1 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -267,12 +267,19 @@ void simuSetSwitch(uint8_t swtch, int8_t state) #endif #if defined(SWITCHES_GPIO_REG_C_L) SWITCH_3_CASE(2, SWITCHES_GPIO_REG_C_L, SWITCHES_GPIO_REG_C_H, SWITCHES_GPIO_PIN_C_L, SWITCHES_GPIO_PIN_C_H) + #endif + #if defined(SWITCHES_GPIO_REG_D_L) SWITCH_3_CASE(3, SWITCHES_GPIO_REG_D_L, SWITCHES_GPIO_REG_D_H, SWITCHES_GPIO_PIN_D_L, SWITCHES_GPIO_PIN_D_H) + #elif defined(SWITCHES_GPIO_REG_D) + SWITCH_CASE (3, SWITCHES_GPIO_REG_D, SWITCHES_GPIO_PIN_D) #endif #if defined(PCBX7) SWITCH_CASE (4, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F) SWITCH_CASE (5, SWITCHES_GPIO_REG_H, SWITCHES_GPIO_PIN_H) - #elif !defined(PCBXLITE) + #elif defined(PCBXLITES) + SWITCH_CASE (4, SWITCHES_GPIO_REG_E, SWITCHES_GPIO_PIN_E) + SWITCH_CASE (5, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F) + #elif !defined(PCBXLITE) && !defined(PCBX3) SWITCH_3_CASE(4, SWITCHES_GPIO_REG_E_L, SWITCHES_GPIO_REG_E_H, SWITCHES_GPIO_PIN_E_L, SWITCHES_GPIO_PIN_E_H) SWITCH_CASE (5, SWITCHES_GPIO_REG_F, SWITCHES_GPIO_PIN_F) SWITCH_3_CASE(6, SWITCHES_GPIO_REG_G_L, SWITCHES_GPIO_REG_G_H, SWITCHES_GPIO_PIN_G_L, SWITCHES_GPIO_PIN_G_H) @@ -327,7 +334,7 @@ void StartSimu(bool tests, const char * sdPath, const char * settingsPath) if (simu_running) return; - s_current_protocol[0] = 255; + moduleSettings[0].protocol = PROTOCOL_CHANNELS_UNINITIALIZED; menuLevel = 0; simu_start_mode = (tests ? 0 : 0x02 /* OPENTX_START_NO_CHECKS */); @@ -693,6 +700,10 @@ uint32_t isBootloaderStart(const uint8_t * block) { return 1; } void LCD_ControlLight(uint16_t dutyCycle) { } #endif +#if defined(PCBXLITES) +bool isJackPlugged() { return false; } +#endif + void serialPrintf(const char * format, ...) { } void serialCrlf() { } void serialPutc(char c) { } diff --git a/radio/src/targets/sky9x/CMakeLists.txt b/radio/src/targets/sky9x/CMakeLists.txt index 2da8e1305..176293564 100644 --- a/radio/src/targets/sky9x/CMakeLists.txt +++ b/radio/src/targets/sky9x/CMakeLists.txt @@ -9,6 +9,7 @@ set(NAVIGATION_TYPE 9x) set(TARGET_DIR sky9x) set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps) set(PPM_LIMITS_SYMETRICAL YES) +set(PXX1 YES) if(PCB STREQUAL 9XRPRO) add_definitions(-Dat91sam3s8 -DREVX) diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index c49fd1119..a37321b1a 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -60,7 +60,7 @@ enum EnumKeys KEY_PLUS = KEY_UP, KEY_RIGHT, KEY_LEFT, - + TRM_BASE, TRM_LH_DWN = TRM_BASE, TRM_LH_UP, @@ -257,10 +257,13 @@ void init_no_pulses(uint32_t port); void disable_no_pulses(uint32_t port); void init_ppm(uint32_t port); void disable_ppm(uint32_t port); -void init_pxx(uint32_t port); -void disable_pxx(uint32_t port); +void init_pxx1_pulses(uint32_t port); +void disable_pxx1_pulses(uint32_t port); void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us); void disable_serial(uint32_t port); +void init_module_timer( uint32_t module_index, uint32_t period, uint8_t state); +void disable_module_timer( uint32_t module_index); +void extmoduleSendNextFrame(); // SD driver #if defined(SIMU) @@ -405,8 +408,9 @@ void debugPutc(const char c); // Telemetry driver void telemetryPortInit(uint32_t baudrate, uint8_t mode); uint32_t telemetryTransmitPending(); -void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size); +void telemetryTransmitBuffer(const uint8_t * buffer, uint32_t size); void rxPdcUsart( void (*pChProcess)(uint8_t x) ); +void sportSendBuffer(const uint8_t * buffer, uint32_t size); // Second UART driver void serial2TelemetryInit(unsigned int protocol); diff --git a/radio/src/targets/sky9x/pulses_driver.cpp b/radio/src/targets/sky9x/pulses_driver.cpp index 02f8d5cf5..4058bedd4 100644 --- a/radio/src/targets/sky9x/pulses_driver.cpp +++ b/radio/src/targets/sky9x/pulses_driver.cpp @@ -23,8 +23,8 @@ void setExternalModulePolarity() { Pwm * pwmptr = PWM; - pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS - if (GET_PPM_POLARITY(EXTERNAL_MODULE)) + pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS + if (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE)) pwmptr->PWM_CH_NUM[3].PWM_CMR &= ~0x00000200; // CPOL else pwmptr->PWM_CH_NUM[3].PWM_CMR |= 0x00000200; // CPOL @@ -33,8 +33,8 @@ void setExternalModulePolarity() void setExtraModulePolarity() { Pwm * pwmptr = PWM; - pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE) * 2; // Duty in half uS - if (GET_PPM_POLARITY(EXTRA_MODULE)) + pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_MODULE_PPM_DELAY(EXTRA_MODULE) * 2; // Duty in half uS + if (GET_MODULE_PPM_POLARITY(EXTRA_MODULE)) pwmptr->PWM_CH_NUM[1].PWM_CMR &= ~0x00000200; // CPOL else pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL @@ -63,8 +63,6 @@ void init_main_ppm(uint32_t period, uint32_t out_enable) { Pwm * pwmptr; - setupPulsesPPMModule(EXTERNAL_MODULE); - if (out_enable) { module_output_active(); } @@ -74,7 +72,7 @@ void init_main_ppm(uint32_t period, uint32_t out_enable) pwmptr->PWM_CH_NUM[3].PWM_CMR = 0x0004000B; // CLKA pwmptr->PWM_CH_NUM[3].PWM_CPDR = period; // Period in half uS pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = period; // Period in half uS - pwmptr->PWM_CH_NUM[3].PWM_CDTY = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS + pwmptr->PWM_CH_NUM[3].PWM_CDTY = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS pwmptr->PWM_ENA = PWM_ENA_CHID3; // Enable channel 3 pwmptr->PWM_IER1 = PWM_IER1_CHID3; @@ -98,13 +96,13 @@ void init_second_ppm(uint32_t period) Pwm * pwmptr = PWM; configure_pins(PIO_PC15, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_NO_PULLUP); pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B; // CLKB - if (!GET_PPM_POLARITY(EXTRA_MODULE)) { + if (!GET_MODULE_PPM_POLARITY(EXTRA_MODULE)) { pwmptr->PWM_CH_NUM[1].PWM_CMR |= 0x00000200; // CPOL } pwmptr->PWM_CH_NUM[1].PWM_CPDR = period; // Period pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = period; // Period - pwmptr->PWM_CH_NUM[1].PWM_CDTY = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty - pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE)*2; // Duty + pwmptr->PWM_CH_NUM[1].PWM_CDTY = GET_MODULE_PPM_DELAY(EXTRA_MODULE)*2; // Duty + pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_MODULE_PPM_DELAY(EXTRA_MODULE)*2; // Duty pwmptr->PWM_ENA = PWM_ENA_CHID1; // Enable channel 1 pwmptr->PWM_IER1 = PWM_IER1_CHID1; #endif @@ -129,6 +127,22 @@ void init_no_pulses(uint32_t port) } } +void init_module_timer(uint32_t port, uint32_t period, uint8_t state) +{ + if (port == EXTERNAL_MODULE) { + // TODO use period here + init_main_ppm(3000, 0); + } +} + +void disable_module_timer(uint32_t port) +{ + if (port == EXTERNAL_MODULE) { + disable_ppm(EXTERNAL_MODULE); + } +} + + void disable_no_pulses(uint32_t port) { if (port == EXTERNAL_MODULE) { @@ -200,7 +214,7 @@ void disable_ssc() sscptr->SSC_CR = SSC_CR_TXDIS; } -void init_pxx(uint32_t port) +void init_pxx1_pulses(uint32_t port) { if (port == EXTERNAL_MODULE) { init_main_ppm(2500 * 2, 0); @@ -211,7 +225,7 @@ void init_pxx(uint32_t port) } } -void disable_pxx(uint32_t port) +void disable_pxx1_pulses(uint32_t port) { if (port == EXTERNAL_MODULE) { disable_ssc(); @@ -251,6 +265,10 @@ void disable_serial(uint32_t port) } } +void extmoduleSendNextFrame() +{ + +} #if !defined(SIMU) extern "C" void PWM_IRQHandler(void) { @@ -260,8 +278,8 @@ extern "C" void PWM_IRQHandler(void) if (reason & PWM_ISR1_CHID3) { // Use the current protocol, don't switch until set_up_pulses - switch (s_current_protocol[EXTERNAL_MODULE]) { - case PROTO_PXX: + switch (moduleSettings[EXTERNAL_MODULE].protocol) { + case PROTOCOL_CHANNELS_PXX1_PULSES: // Alternate periods of 6.5mS and 2.5 mS period = pwmptr->PWM_CH_NUM[3].PWM_CPDR; if (period == 2500 * 2) { @@ -278,15 +296,15 @@ extern "C" void PWM_IRQHandler(void) else { // Kick off serial output here Ssc * sscptr = SSC; - sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.getData()); - sscptr->SSC_TCR = modulePulsesData[EXTERNAL_MODULE].pxx.getSize(); + sscptr->SSC_TPR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); + sscptr->SSC_TCR = extmodulePulsesData.pxx.getSize(); sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers } break; - case PROTO_DSM2_LP45: - case PROTO_DSM2_DSM2: - case PROTO_DSM2_DSMX: + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: // Alternate periods of 19.5mS and 2.5 mS period = pwmptr->PWM_CH_NUM[3].PWM_CPDR; if (period == 2500 * 2) { @@ -302,16 +320,16 @@ extern "C" void PWM_IRQHandler(void) else { // Kick off serial output here Ssc * sscptr = SSC; - sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); - sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + sscptr->SSC_TPR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); + sscptr->SSC_TCR = (uint8_t *)extmodulePulsesData.dsm2.ptr - (uint8_t *)extmodulePulsesData.dsm2.pulses; sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers } break; #if defined(MULTIMODULE) - case PROTO_MULTIMODULE: + case PROTOCOL_CHANNELS_MULTIMODULE: #endif - case PROTO_SBUS: + case PROTOCOL_CHANNELS_SBUS: // Todo: how to do inverted polarity on this platform? // Alternate periods of 5.5mS and 3.5 mS period = pwmptr->PWM_CH_NUM[3].PWM_CPDR; @@ -328,15 +346,15 @@ extern "C" void PWM_IRQHandler(void) else { // Kick off serial output here Ssc * sscptr = SSC; - sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); - sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + sscptr->SSC_TPR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); + sscptr->SSC_TCR = (uint8_t *)extmodulePulsesData.dsm2.ptr - (uint8_t *)extmodulePulsesData.dsm2.pulses; sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers } break; default: - pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++; - if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) { + pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = *extmodulePulsesData.ppm.ptr++; + if (*extmodulePulsesData.ppm.ptr == 0) { setExternalModulePolarity(); setupPulses(EXTERNAL_MODULE); } @@ -347,11 +365,12 @@ extern "C" void PWM_IRQHandler(void) #if !defined(REVA) if (reason & PWM_ISR1_CHID1) { - pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = *modulePulsesData[EXTRA_MODULE].ppm.ptr++; + // TODO EXTRA_MODULE will be broken + /*pwmptr->PWM_CH_NUM[1].PWM_CPDRUPD = *modulePulsesData[EXTRA_MODULE].ppm.ptr++; if (*modulePulsesData[EXTRA_MODULE].ppm.ptr == 0) { - setupPulsesPPMModule(EXTRA_MODULE); + setupPulses(EXTRA_MODULE); setExtraModulePolarity(); - } + }*/ } #endif } diff --git a/radio/src/targets/sky9x/telemetry_driver.cpp b/radio/src/targets/sky9x/telemetry_driver.cpp index e9dc3edaa..4875c5d35 100644 --- a/radio/src/targets/sky9x/telemetry_driver.cpp +++ b/radio/src/targets/sky9x/telemetry_driver.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -135,12 +135,11 @@ void rxPdcUsart( void (*pChProcess)(uint8_t x) ) #endif } -uint32_t txPdcUsart(uint8_t *buffer, uint32_t size) +uint32_t txPdcUsart(const uint8_t * buffer, uint32_t size) { - Usart *pUsart = SECOND_USART; + Usart * pUsart = SECOND_USART; - if ( pUsart->US_TNCR == 0 ) - { + if (pUsart->US_TNCR == 0) { #ifndef SIMU pUsart->US_TNPR = (uint32_t)buffer ; #endif @@ -174,7 +173,12 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) #endif } -void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size) +void sportSendBuffer(const uint8_t * buffer, uint32_t size) +{ + telemetryTransmitBuffer(buffer, size); +} + +void telemetryTransmitBuffer(const uint8_t * buffer, uint32_t size) { txPdcUsart(buffer, size); } diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 78b09bfb5..0a6a952eb 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -31,6 +31,7 @@ if(PCB STREQUAL X9E) set(FONTS_TARGET taranis_fonts) set(LCD_DRIVER lcd_driver_spi.cpp) set(GVAR_SCREEN model_gvars.cpp) + set(STATUS_LEDS NO) elseif(PCB STREQUAL X9D+) set(CPU_TYPE STM32F2) set(CPU_TYPE_FULL STM32F205xE) # for size report @@ -47,6 +48,7 @@ elseif(PCB STREQUAL X9D+) set(LCD_DRIVER lcd_driver_spi.cpp) set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp) set(GVAR_SCREEN model_gvars.cpp) + set(STATUS_LEDS NO) elseif(PCB STREQUAL X9D) set(CPU_TYPE STM32F2) set(CPU_TYPE_FULL STM32F205xE) # for size report @@ -63,6 +65,7 @@ elseif(PCB STREQUAL X9D) set(LCD_DRIVER lcd_driver_aspi.cpp) set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp) set(GVAR_SCREEN model_gvars.cpp) + set(STATUS_LEDS NO) elseif(PCB STREQUAL X7) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F2) @@ -80,8 +83,28 @@ elseif(PCB STREQUAL X7) 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 X3) + 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_x3) + set(FLAVOUR x3) + add_definitions(-DPCBX3 -DSOFTWARE_VOLUME) + add_definitions(-DEEPROM_VARIANT=0x4000) + add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) + 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) - set(PXX_FREQUENCY "HIGH" CACHE STRING "PXX frequency (LOW / HIGH)") + 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) set(CPU_TYPE_FULL STM32F205xE) # for size report @@ -89,7 +112,7 @@ elseif(PCB STREQUAL XLITE) set(HAPTIC YES) set(LUA_EXPORT lua_export_xlite) set(FLAVOUR xlite) - add_definitions(-DPCBXLITE -DSOFTWARE_VOLUME) + add_definitions(-DPCBXLITE -DSOFTWARE_VOLUME -DEXTERNAL_ANTENNA -DSTICKS_PWM) add_definitions(-DEEPROM_VARIANT=0x2000) add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) set(GUI_DIR 128x64) @@ -98,9 +121,40 @@ elseif(PCB STREQUAL XLITE) 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 XLITES) + 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_xlite) + set(FLAVOUR xlites) + add_definitions(-DPCBXLITES -DPCBXLITE -DSOFTWARE_VOLUME -DEXTERNAL_ANTENNA -DSTICKS_PWM) + add_definitions(-DEEPROM_VARIANT=0x1000) + add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) + set(GUI_DIR 128x64) + set(NAVIGATION_TYPE xlite) + 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) endif() -if(PCB STREQUAL XLITE) +#if(PCB STREQUAL XLITES) +# add_definitions(-DGYRO) +# set(TARGET_SRC +# ${TARGET_SRC} +# ../common/arm/stm32/lsm6ds3_driver.cpp +# ) +#endif() + +if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCB STREQUAL X3) + option(PXX1 "PXX1 protocol support" OFF) + option(PXX2 "PXX2 protocol support" ON) + add_definitions(-DINTERNAL_MODULE_SERIAL) if(PXX_FREQUENCY STREQUAL HIGH) add_definitions(-DPXX_FREQUENCY_HIGH) endif() @@ -112,19 +166,26 @@ if(PCB STREQUAL XLITE) ../common/arm/stm32/intmodule_serial_driver.cpp ) else() + set(PXX1 YES) + option(PXX2 "PXX2 protocol support" ON) set(TARGET_SRC ${TARGET_SRC} intmodule_pulses_driver.cpp - trainer_driver.cpp ) - add_definitions(-DSBUS) set(PULSES_SRC ${PULSES_SRC} ../sbus.cpp ) endif() -if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE) +if(NOT PCB STREQUAL XLITE) + set(TARGET_SRC + ${TARGET_SRC} + trainer_driver.cpp + ) +endif() + +if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES) add_definitions(-DBLUETOOTH) set(TARGET_SRC ${TARGET_SRC} @@ -149,7 +210,13 @@ endif() add_definitions(-DPCBTARANIS) add_definitions(-DAUDIO -DVOICE -DRTCLOCK) -set(GUI_SRC ${GUI_SRC} +set(SRC + ${SRC} + io/frsky_device_firmware_update.cpp + ) + +set(GUI_SRC + ${GUI_SRC} model_input_edit.cpp model_mix_edit.cpp model_display.cpp @@ -163,7 +230,7 @@ set(GUI_SRC ${GUI_SRC} ../screenshot.cpp ) -if(PCB STREQUAL X7 OR PCB STREQUAL XLITE) +if(STATUS_LEDS) set(LED_DRIVER led_driver.cpp) endif() @@ -177,7 +244,7 @@ set(TARGET_SRC ../common/arm/stm32/adc_driver.cpp ) -if(PCB STREQUAL XLITE) +if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES) set(TARGET_SRC ${TARGET_SRC} ../common/arm/stm32/sticks_pwm_driver.cpp diff --git a/radio/src/targets/taranis/backlight_driver.cpp b/radio/src/targets/taranis/backlight_driver.cpp index 97b225ac9..83e774ea2 100644 --- a/radio/src/targets/taranis/backlight_driver.cpp +++ b/radio/src/targets/taranis/backlight_driver.cpp @@ -97,7 +97,7 @@ uint8_t isBacklightEnabled() { return (BACKLIGHT_TIMER->CCR4 != 0 || BACKLIGHT_TIMER->CCR2 != 0); } -#elif defined(PCBX7) || defined(PCBXLITE) +#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) void backlightInit() { GPIO_InitTypeDef GPIO_InitStructure; diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 5c092ee03..6a8bfcf5f 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -29,6 +29,8 @@ extern "C" { } #endif +HardwareOptions hardwareOptions; + void watchdogInit(unsigned int duration) { IWDG->KR = 0x5555; // Unlock registers @@ -149,20 +151,25 @@ void boardInit() INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | TELEMETRY_RCC_AHB1Periph | SPORT_UPDATE_RCC_AHB1Periph | SERIAL_RCC_AHB1Periph | TRAINER_RCC_AHB1Periph | - HEARTBEAT_RCC_AHB1Periph | BT_RCC_AHB1Periph, ENABLE); + HEARTBEAT_RCC_AHB1Periph | BT_RCC_AHB1Periph | GYRO_RCC_AHB1Periph, + ENABLE); RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | AUDIO_RCC_APB1Periph | ADC_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | HAPTIC_RCC_APB1Periph | INTERRUPT_xMS_RCC_APB1Periph | TIMER_2MHz_RCC_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph | - INTMODULE_RCC_APB1Periph | BT_RCC_APB1Periph, ENABLE); + INTMODULE_RCC_APB1Periph | BT_RCC_APB1Periph | GYRO_RCC_APB1Periph, ENABLE); RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph | ADC_RCC_APB2Periph | HAPTIC_RCC_APB2Periph | INTMODULE_RCC_APB2Periph | EXTMODULE_RCC_APB2Periph | HEARTBEAT_RCC_APB2Periph | BT_RCC_APB2Periph, ENABLE); +#if defined(BLUETOOTH) + bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE); +#endif + #if !defined(PCBX9E) // some X9E boards need that the pwrInit() is moved a little bit later pwrInit(); @@ -180,7 +187,7 @@ void boardInit() sticksPwmInit(); delay_ms(20); if (pwm_interrupt_count < 32) { - sticks_pwm_disabled = true; + hardwareOptions.sticksPwmDisabled = true; } #endif @@ -202,8 +209,8 @@ void boardInit() hapticInit(); #endif -#if defined(BLUETOOTH) - bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE); +#if defined(PXX2_PROBE) + intmodulePxx2Probe(); #endif #if defined(DEBUG) @@ -272,6 +279,17 @@ void boardInit() if (HAS_SPORT_UPDATE_CONNECTOR()) { sportUpdateInit(); } + +#if defined(JACK_DETECT_GPIO) + initJackDetect(); +#endif + + initSpeakerEnable(); + enableSpeaker(); + + initHeadphoneTrainerSwitch(); + + vbattRTC = getRTCBattVoltage(); #endif // !defined(SIMU) } @@ -302,7 +320,7 @@ uint8_t currentTrainerMode = 0xff; void checkTrainerSettings() { - uint8_t requiredTrainerMode = g_model.trainerMode; + uint8_t requiredTrainerMode = g_model.trainerData.mode; if (requiredTrainerMode != currentTrainerMode) { switch (currentTrainerMode) { case TRAINER_MODE_MASTER_TRAINER_JACK: @@ -357,3 +375,65 @@ uint16_t getBatteryVoltage() instant_vbat += 20; // add 0.2V because of the diode TODO check if this is needed, but removal will beak existing calibrations!!! return (uint16_t)instant_vbat; } + +#if defined(AUDIO_SPEAKER_ENABLE_GPIO) +void initSpeakerEnable() +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = AUDIO_SPEAKER_ENABLE_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(AUDIO_SPEAKER_ENABLE_GPIO, &GPIO_InitStructure); +} + +void enableSpeaker() +{ + GPIO_SetBits(AUDIO_SPEAKER_ENABLE_GPIO, AUDIO_SPEAKER_ENABLE_GPIO_PIN); +} + +void disableSpeaker() +{ + GPIO_ResetBits(AUDIO_SPEAKER_ENABLE_GPIO, AUDIO_SPEAKER_ENABLE_GPIO_PIN); +} +#endif + +#if defined(HEADPHONE_TRAINER_SWITCH_GPIO) +void initHeadphoneTrainerSwitch() +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = HEADPHONE_TRAINER_SWITCH_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(HEADPHONE_TRAINER_SWITCH_GPIO, &GPIO_InitStructure); +} + +void enableHeadphone() +{ + GPIO_ResetBits(HEADPHONE_TRAINER_SWITCH_GPIO, HEADPHONE_TRAINER_SWITCH_GPIO_PIN); +} + +void enableTrainer() +{ + GPIO_SetBits(HEADPHONE_TRAINER_SWITCH_GPIO, HEADPHONE_TRAINER_SWITCH_GPIO_PIN); +} +#endif + +#if defined(JACK_DETECT_GPIO) +void initJackDetect(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.GPIO_Pin = JACK_DETECT_GPIO_PIN; + 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_UP; + GPIO_Init(JACK_DETECT_GPIO, &GPIO_InitStructure); +} +#endif \ No newline at end of file diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index be890a8ad..650e6625e 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -21,8 +21,9 @@ #ifndef _BOARD_H_ #define _BOARD_H_ -#include "stddef.h" -#include "stdbool.h" +#include +#include "../definitions.h" +#include "cpu_id.h" #if defined(__cplusplus) && !defined(SIMU) extern "C" { @@ -124,10 +125,6 @@ void delay_ms(uint32_t ms); } #endif -// CPU Unique ID -#define LEN_CPU_UID (3*8+2) -void getCPUUniqueID(char * s); - // SD driver #define BLOCK_SIZE 512 /* Block Size in Bytes */ #if !defined(SIMU) || defined(SIMU_DISKIO) @@ -168,35 +165,58 @@ uint32_t isBootloaderStart(const uint8_t * buffer); // Pulses driver #define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) -#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) -#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) -#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) -#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) -#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) -#if defined(INTMODULE_USART) && defined(EXTMODULE_USART) - #define IS_UART_MODULE(port) (true) -#elif defined(INTMODULE_USART) - #define IS_UART_MODULE(port) (port == INTERNAL_MODULE) +#if defined(INTMODULE_USART) + #define INTERNAL_MODULE_OFF() intmoduleStop() #else - #define IS_UART_MODULE(port) (false) + #define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) #endif -void init_no_pulses(uint32_t port); -void disable_no_pulses(uint32_t port); -void init_ppm( uint32_t module_index); -void disable_ppm( uint32_t module_index); -void init_pxx( uint32_t module_index); -void disable_pxx( uint32_t module_index); -void init_serial( uint32_t module_index, uint32_t baudrate, uint32_t period); -void disable_serial( uint32_t module_index); -void init_module_timer( uint32_t module_index, uint32_t period, uint8_t state); -void disable_module_timer( uint32_t module_index); + +#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) + +void init_ppm(uint8_t module); +void disable_ppm(uint8_t module); +void init_pxx2(uint8_t module); +void disable_pxx2(uint8_t module); +void init_pxx1_pulses(uint8_t module); +void init_pxx1_serial(uint8_t module); +void disable_pxx1_pulses(uint8_t module); +void disable_pxx1_serial(uint8_t module); +void init_serial(uint8_t module, uint32_t baudrate, uint32_t period); +void disable_serial(uint8_t module); +void intmoduleStop(); +void intmodulePxxStart(); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); +#if defined(TARANIS_INTERNAL_PPM) +void intmodulePpmStart(void); +#endif +void intmoduleSendBuffer(const uint8_t * data, uint8_t size); +void intmoduleSendNextFrame(); + +void extmoduleStop(); +void extmodulePpmStart(); +void extmodulePxxPulsesStart(); +void extmodulePxxSerialStart(); +void extmodulePxx2Start(); +void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us); +void extmoduleInvertedSerialStart(uint32_t baudrate); +void extmoduleSendBuffer(const uint8_t * data, uint8_t size); +void extmoduleSendNextFrame(); // Trainer driver -#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE) +#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) #if defined(PCBX9E) #define TRAINER_CONNECTED() (true) -#elif defined(PCBX7) +#elif defined(PCBX7) || defined(PCBX3) #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET) +#elif defined(PCBXLITES) + enum JackState + { + SPEAKER_ACTIVE, + HEADPHONE_ACTIVE, + TRAINER_ACTIVE, + }; + extern uint8_t jackState; + #define TRAINER_CONNECTED() (jackState == TRAINER_ACTIVE) #elif defined(PCBXLITE) #define TRAINER_CONNECTED() false // there is no Trainer jack on Taranis X-Lite #else @@ -310,25 +330,27 @@ enum EnumSwitchesPositions SW_SC0, SW_SC1, SW_SC2, +#if !defined(PCBX3) SW_SD0, SW_SD1, SW_SD2, -#if !defined(PCBX7) && !defined(PCBXLITE) +#endif +#if defined(PCBX9) || defined(PCBXLITES) || defined(PCBX3) SW_SE0, SW_SE1, SW_SE2, #endif -#if !defined(PCBXLITE) +#if defined(PCBX9) || defined(PCBX7) || defined(PCBXLITES) || defined(PCBX3) SW_SF0, SW_SF1, SW_SF2, #endif -#if !defined(PCBX7) && !defined(PCBXLITE) +#if defined(PCBX9) SW_SG0, SW_SG1, SW_SG2, #endif -#if !defined(PCBXLITE) +#if defined(PCBX9) || defined(PCBX7) SW_SH0, SW_SH1, SW_SH2, @@ -365,11 +387,16 @@ enum EnumSwitchesPositions SW_SR1, SW_SR2, #endif + NUM_SWITCHES_POSITIONS }; -#if defined(PCBXLITE) +#if defined(PCBXLITES) + #define NUM_SWITCHES 6 +#elif defined(PCBXLITE) #define NUM_SWITCHES 4 #elif defined(PCBX7) #define NUM_SWITCHES 6 +#elif defined(PCBX3) + #define NUM_SWITCHES 5 #elif defined(PCBX9E) #define NUM_SWITCHES 18 // yes, it's a lot! #else @@ -383,7 +410,7 @@ uint32_t readTrims(void); #define TRIMS_PRESSED() (readTrims()) #define KEYS_PRESSED() (readKeys()) -#if defined(PCBX9E) || defined(PCBX7) +#if defined(PCBX9E) || defined(PCBX7) || defined(PCBX3) // Rotary Encoder driver #define ROTARY_ENCODER_NAVIGATION void checkRotaryEncoder(void); @@ -412,10 +439,13 @@ enum Analogs { STICK4, POT_FIRST, POT1 = POT_FIRST, +#if defined(PCBX3) + POT_LAST = POT1, +#elif defined(PCBXLITE) || defined(PCBX7) POT2, -#if defined(PCBX7) || defined(PCBXLITE) POT_LAST = POT2, #elif defined(PCBX9E) + POT2, POT3, POT4, POT_LAST = POT4, @@ -424,13 +454,15 @@ enum Analogs { SLIDER3, SLIDER4, #else + POT2, POT3, POT_LAST = POT3, SLIDER1, SLIDER2, #endif TX_VOLTAGE, - NUM_ANALOGS + NUM_ANALOGS, + TX_RTC = NUM_ANALOGS }; #define NUM_POTS (POT_LAST-POT_FIRST+1) @@ -440,18 +472,39 @@ enum Analogs { #define NUM_MOUSE_ANALOGS 0 #define NUM_DUMMY_ANAS 0 -#if defined(PCBXLITE) +#if defined(STICKS_PWM) #define NUM_PWMSTICKS 4 - extern bool sticks_pwm_disabled; - #define STICKS_PWM_ENABLED() (sticks_pwm_disabled == false) + #define STICKS_PWM_ENABLED() (!hardwareOptions.sticksPwmDisabled) void sticksPwmInit(void); void sticksPwmRead(uint16_t * values); - extern volatile uint32_t pwm_interrupt_count; + extern volatile uint32_t pwm_interrupt_count; // TODO => reusable buffer (boot section) #define NUM_TRIMS_KEYS 4 #else #define NUM_TRIMS_KEYS 8 #endif +PACK(typedef struct { +#if NUM_PWMSTICKS > 0 + uint8_t sticksPwmDisabled:1; +#endif + uint8_t pxx2Enabled:1; +}) HardwareOptions; + +extern HardwareOptions hardwareOptions; + +#if !defined(PXX2) + #define IS_PXX2_INTERNAL_ENABLED() (false) + #define IS_PXX1_INTERNAL_ENABLED() (true) +#elif !defined(PXX1) || defined(PCBXLITES) || defined(PCBX3) + #define IS_PXX2_INTERNAL_ENABLED() (true) + #define IS_PXX1_INTERNAL_ENABLED() (false) +#else + // TODO #define PXX2_PROBE + // TODO #define IS_PXX2_INTERNAL_ENABLED() (hardwareOptions.pxx2Enabled) + #define IS_PXX2_INTERNAL_ENABLED() (true) + #define IS_PXX1_INTERNAL_ENABLED() (true) +#endif + enum CalibratedAnalogs { CALIBRATED_STICK1, CALIBRATED_STICK2, @@ -469,11 +522,14 @@ enum CalibratedAnalogs { #else #define IS_POT(x) ((x)>=POT_FIRST && (x)<=POT_LAST) #endif + #define IS_SLIDER(x) ((x)>POT_LAST && (x)CR1 &= ~TIM_CR1_CEN; - EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = (2000 * period); - EXTMODULE_TIMER->CCR2 = (2000 * period) - 1000; - EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - - NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); -} - void extmodulePpmStart() { EXTERNAL_MODULE_ON(); @@ -89,17 +56,18 @@ void extmodulePpmStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz EXTMODULE_TIMER->ARR = 45000; - EXTMODULE_TIMER->CCR1 = GET_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here + EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE)*2; + EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high EXTMODULE_TIMER->EGR = 1; EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1 + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - extmoduleSendNextFrame(); - NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); @@ -130,10 +98,11 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - extmoduleSendNextFrame(); - NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); @@ -141,7 +110,9 @@ void extmoduleSerialStart(uint32_t /*baudrate*/, uint32_t period_half_us) } #if defined(EXTMODULE_USART) -void extmoduleInvertedSerialStart(uint32_t baudrate, uint32_t period_half_us) +ModuleFifo extmoduleFifo; + +void extmoduleInvertedSerialStart(uint32_t baudrate) { EXTERNAL_MODULE_ON(); @@ -152,23 +123,17 @@ void extmoduleInvertedSerialStart(uint32_t baudrate, uint32_t period_half_us) NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - // TX Pin - GPIO_PinAFConfig(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_USART_TX_GPIO_AF); + // TX + RX Pins + GPIO_PinAFConfig(EXTMODULE_USART_GPIO, EXTMODULE_TX_GPIO_PinSource, EXTMODULE_USART_GPIO_AF); + GPIO_PinAFConfig(EXTMODULE_USART_GPIO, EXTMODULE_RX_GPIO_PinSource, EXTMODULE_USART_GPIO_AF); GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN | EXTMODULE_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); - -#if 0 - // RX Pin - GPIO_PinAFConfig(EXTMODULE_RX_GPIO, EXTMODULE_RX_GPIO_PinSource, EXTMODULE_TX_GPIO_USART_AF); - GPIO_InitStructure.GPIO_Pin = EXTMODULE_RX_GPIO_PIN; - GPIO_Init(EXTMODULE_RX_GPIO, &GPIO_InitStructure); -#endif + GPIO_Init(EXTMODULE_USART_GPIO, &GPIO_InitStructure); // UART config USART_DeInit(EXTMODULE_USART); @@ -178,30 +143,78 @@ void extmoduleInvertedSerialStart(uint32_t baudrate, uint32_t period_half_us) USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(EXTMODULE_USART, &USART_InitStructure); USART_Cmd(EXTMODULE_USART, ENABLE); - // Timer - EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - EXTMODULE_TIMER->ARR = period_half_us; - EXTMODULE_TIMER->CCR2 = period_half_us - 2000; // Update time - EXTMODULE_TIMER->EGR = 1; // Restart - EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt - EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; + extmoduleFifo.clear(); - NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); - NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7); + USART_ITConfig(EXTMODULE_USART, USART_IT_RXNE, ENABLE); + NVIC_SetPriority(EXTMODULE_USART_IRQn, 6); + NVIC_EnableIRQ(EXTMODULE_USART_IRQn); } -void extmodulePxxStart() +void extmoduleSendBuffer(const uint8_t * data, uint8_t size) { - extmoduleInvertedSerialStart(EXTMODULE_USART_PXX_BAUDRATE, PXX_PERIOD_HALF_US); + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(EXTMODULE_USART_DMA_STREAM); + DMA_InitStructure.DMA_Channel = EXTMODULE_USART_DMA_CHANNEL; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(data); + DMA_InitStructure.DMA_BufferSize = size; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(EXTMODULE_USART_DMA_STREAM, &DMA_InitStructure); + DMA_Cmd(EXTMODULE_USART_DMA_STREAM, ENABLE); + USART_DMACmd(EXTMODULE_USART, USART_DMAReq_Tx, ENABLE); +} + +// TODO remove this when we have adaptative speed +//uint8_t counter = 0; +//#include + +#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +extern "C" void EXTMODULE_USART_IRQHandler(void) +{ + uint32_t status = EXTMODULE_USART->SR; + + while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { + uint8_t data = EXTMODULE_USART->DR; + if (status & USART_FLAG_ERRORS) { + extmoduleFifo.errors++; +// if (!counter++) { +// TRACE_NOCRLF("%02X ", (uint8_t)status); +// } + } + else { + extmoduleFifo.push(data); + } + status = EXTMODULE_USART->SR; + } +} + +void extmodulePxx2Start() +{ + extmoduleInvertedSerialStart(EXTMODULE_USART_PXX2_BAUDRATE); } #else -void extmodulePxxStart() +void extmodulePxx2Start() +{ + // TODO just enable the S.PORT line (or let telemetry init do it) +} +#endif + +#if defined(PXX1) +void extmodulePxxPulsesStart() { EXTERNAL_MODULE_ON(); @@ -217,7 +230,7 @@ void extmodulePxxStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) - EXTMODULE_TIMER->ARR = PXX_PERIOD_HALF_US; + EXTMODULE_TIMER->ARR = PXX_PULSES_PERIOD * 2000; // 0.5uS (2Mhz) EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | EXTMODULE_TIMER_OUTPUT_POLARITY; // polarity, default low EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 18; @@ -225,10 +238,11 @@ void extmodulePxxStart() EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; + EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + EXTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - extmoduleSendNextFrame(); - NVIC_EnableIRQ(EXTMODULE_TIMER_DMA_STREAM_IRQn); NVIC_SetPriority(EXTMODULE_TIMER_DMA_STREAM_IRQn, 7); NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn); @@ -236,65 +250,83 @@ void extmodulePxxStart() } #endif +#if defined(PXX1) && defined(EXTMODULE_USART) +void extmodulePxxSerialStart() +{ + extmoduleInvertedSerialStart(EXTMODULE_PXX_SERIAL_BAUDRATE); +} +#endif + void extmoduleSendNextFrame() { - if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) { - EXTMODULE_TIMER->CCR1 = GET_PPM_DELAY(EXTERNAL_MODULE)*2; - EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here - EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].ppm.ptr - 1) - 4000; // 2mS in advance - EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].ppm.pulses); - EXTMODULE_TIMER_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].ppm.ptr - modulePulsesData[EXTERNAL_MODULE].ppm.pulses; - EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } - else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) { -#if defined(EXTMODULE_USART) - DMA_InitTypeDef DMA_InitStructure; - DMA_DeInit(EXTMODULE_USART_DMA_STREAM); - DMA_InitStructure.DMA_Channel = EXTMODULE_USART_DMA_CHANNEL; - DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&EXTMODULE_USART->DR); - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx_uart.getData()); - DMA_InitStructure.DMA_BufferSize = modulePulsesData[EXTERNAL_MODULE].pxx_uart.getSize(); - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(EXTMODULE_USART_DMA_STREAM, &DMA_InitStructure); - DMA_Cmd(EXTMODULE_USART_DMA_STREAM, ENABLE); - USART_DMACmd(EXTMODULE_USART, USART_DMAReq_Tx, ENABLE); - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; -#else - EXTMODULE_TIMER->CCR2 = modulePulsesData[EXTERNAL_MODULE].pxx.getLast() - 4000; // 2mS in advance - EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.getData()); - EXTMODULE_TIMER_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.getSize(); - EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + switch(moduleSettings[EXTERNAL_MODULE].protocol) { + case PROTOCOL_CHANNELS_PPM: + EXTMODULE_TIMER->CCR1 = GET_MODULE_PPM_DELAY(EXTERNAL_MODULE) * 2; + EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_MODULE_PPM_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // // we are using complementary output so logic has to be reversed here + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.ppm.pulses); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.ppm.ptr - extmodulePulsesData.ppm.pulses; + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; + +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_PULSES: + EXTMODULE_TIMER->CCR2 = extmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.pxx.getData()); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.pxx.getSize(); + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; #endif - } - else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { - if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + +#if defined(PXX1) && defined(EXTMODULE_USART) + case PROTOCOL_CHANNELS_PXX1_SERIAL: + extmoduleSendBuffer(extmodulePulsesData.pxx_uart.getData(), extmodulePulsesData.pxx_uart.getSize()); + break; +#endif + +#if defined(PXX2) + case PROTOCOL_CHANNELS_PXX2: + #if defined(EXTMODULE_USART) + extmoduleSendBuffer(extmodulePulsesData.pxx2.getData(), extmodulePulsesData.pxx2.getSize()); + #else + sportSendBuffer(extmodulePulsesData.pxx2.getData(), extmodulePulsesData.pxx2.getSize()); + #endif + break; +#endif + +#if defined(DSM2) + case PROTOCOL_CHANNELS_SBUS: EXTMODULE_TIMER->CCER = EXTMODULE_TIMER_OUTPUT_ENABLE | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? EXTMODULE_TIMER_OUTPUT_POLARITY : 0); // reverse polarity for Sbus if needed - EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance - EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); - EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); - EXTMODULE_TIMER_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; - EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } - else { - EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + // no break + case PROTOCOL_CHANNELS_DSM2_LP45: + case PROTOCOL_CHANNELS_DSM2_DSM2: + case PROTOCOL_CHANNELS_DSM2_DSMX: + case PROTOCOL_CHANNELS_MULTIMODULE: + EXTMODULE_TIMER->CCR2 = *(extmodulePulsesData.dsm2.ptr - 1) - 4000; // 2mS in advance + EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); + EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(extmodulePulsesData.dsm2.pulses); + EXTMODULE_TIMER_DMA_STREAM->NDTR = extmodulePulsesData.dsm2.ptr - extmodulePulsesData.dsm2.pulses; + EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; +#endif + +#if defined(CROSSFIRE) + case PROTOCOL_CHANNELS_CROSSFIRE: + sportSendBuffer(extmodulePulsesData.crossfire.pulses, extmodulePulsesData.crossfire.length); + break; +#endif + + default: + EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + break; } } @@ -313,6 +345,7 @@ extern "C" void EXTMODULE_TIMER_CC_IRQHandler() { EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - setupPulses(EXTERNAL_MODULE); - extmoduleSendNextFrame(); + if (setupPulses(EXTERNAL_MODULE)) { + extmoduleSendNextFrame(); + } } diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 716bae368..6f12e32d7 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -55,6 +55,15 @@ #define KEYS_GPIO_PIN_EXIT GPIO_Pin_2 // PD.02 #define KEYS_GPIO_REG_ENTER GPIOE->IDR #define KEYS_GPIO_PIN_ENTER GPIO_Pin_10 // PE.10 +#elif defined(PCBX3) + #define KEYS_GPIO_REG_PAGE GPIOE->IDR + #define KEYS_GPIO_PIN_PAGE GPIO_Pin_8 // PE.08 + #define KEYS_GPIO_REG_MENU GPIOE->IDR + #define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PE.07 + #define KEYS_GPIO_REG_EXIT GPIOE->IDR + #define KEYS_GPIO_PIN_EXIT GPIO_Pin_9 // PE.09 + #define KEYS_GPIO_REG_ENTER GPIOE->IDR + #define KEYS_GPIO_PIN_ENTER GPIO_Pin_11 // PE.11 #else #define KEYS_GPIO_REG_MENU GPIOD->IDR #define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PD.07 @@ -81,10 +90,15 @@ #define ENC_GPIO_PIN_A GPIO_Pin_9 // PE.09 #define ENC_GPIO_PIN_B GPIO_Pin_11 // PE.11 #define ROTARY_ENCODER_POSITION() (((ENC_GPIO->IDR >> 10) & 0x02) + ((ENC_GPIO->IDR >> 9) & 0x01)) +#elif defined(PCBX3) + #define ENC_GPIO GPIOE + #define ENC_GPIO_PIN_A GPIO_Pin_10 // PE.10 + #define ENC_GPIO_PIN_B GPIO_Pin_12 // PE.12 + #define ROTARY_ENCODER_POSITION() (((ENC_GPIO->IDR >> 12) & 0x01) + ((ENC_GPIO->IDR >> 9) & 0x02)) #endif // This is for SIMU: reuse rotary encoder pins to map UP and DOWN keyboard keys -#if defined(SIMU) && (defined(PCBX9E) || defined(PCBX7)) +#if defined(SIMU) && (defined(PCBX9E) || defined(PCBX7) || defined(PCBX3)) #define KEYS_GPIO_REG_PLUS ENC_GPIO->IDR #define KEYS_GPIO_PIN_PLUS ENC_GPIO_PIN_A #define KEYS_GPIO_REG_MINUS ENC_GPIO->IDR @@ -135,6 +149,23 @@ #define TRIMS_GPIO_PIN_RVU GPIO_Pin_2 // PC.02 #define TRIMS_GPIO_REG_RHR GPIOE->IDR #define TRIMS_GPIO_PIN_RHR GPIO_Pin_4 // PE.04 +#elif defined(PCBX3) + #define TRIMS_GPIO_REG_LHR GPIOC->IDR + #define TRIMS_GPIO_PIN_LHR GPIO_Pin_4 // PC.04 + #define TRIMS_GPIO_REG_LHL GPIOC->IDR + #define TRIMS_GPIO_PIN_LHL GPIO_Pin_5 // PC.05 + #define TRIMS_GPIO_REG_LVU GPIOB->IDR + #define TRIMS_GPIO_PIN_LVU GPIO_Pin_0 // PB.00 + #define TRIMS_GPIO_REG_LVD GPIOB->IDR + #define TRIMS_GPIO_PIN_LVD GPIO_Pin_1 // PB.01 + #define TRIMS_GPIO_REG_RVU GPIOE->IDR + #define TRIMS_GPIO_PIN_RVU GPIO_Pin_13 // PE.13 + #define TRIMS_GPIO_REG_RHR GPIOD->IDR + #define TRIMS_GPIO_PIN_RHR GPIO_Pin_8 // PD.08 + #define TRIMS_GPIO_REG_RVD GPIOE->IDR + #define TRIMS_GPIO_PIN_RVD GPIO_Pin_14 // PE.14 + #define TRIMS_GPIO_REG_RHL GPIOD->IDR + #define TRIMS_GPIO_PIN_RHL GPIO_Pin_9 // PD.09 #else #define TRIMS_GPIO_REG_LHL GPIOE->IDR #define TRIMS_GPIO_PIN_LHL GPIO_Pin_4 // PE.04 @@ -160,7 +191,7 @@ #define SWITCHES_GPIO_PIN_A_H GPIO_Pin_10 // PD.10 #define SWITCHES_GPIO_REG_A_L GPIOD->IDR #define SWITCHES_GPIO_PIN_A_L GPIO_Pin_14 // PD.14 -#elif defined(PCBXLITE) +#elif defined(PCBXLITE) || defined(PCBX3) #define SWITCHES_GPIO_REG_A_H GPIOE->IDR #define SWITCHES_GPIO_PIN_A_H GPIO_Pin_1 // PE.01 #define SWITCHES_GPIO_REG_A_L GPIOE->IDR @@ -192,6 +223,11 @@ #define SWITCHES_GPIO_PIN_B_L GPIO_Pin_15 // PE.15 #define SWITCHES_GPIO_REG_B_H GPIOA->IDR #define SWITCHES_GPIO_PIN_B_H GPIO_Pin_5 // PA.05 +#elif defined(PCBX3) + #define SWITCHES_GPIO_REG_B_L GPIOB->IDR + #define SWITCHES_GPIO_PIN_B_L GPIO_Pin_4 // PB.04 + #define SWITCHES_GPIO_REG_B_H GPIOB->IDR + #define SWITCHES_GPIO_PIN_B_H GPIO_Pin_5 // PB.05 #else #define SWITCHES_GPIO_REG_B_H GPIOE->IDR #define SWITCHES_GPIO_PIN_B_H GPIO_Pin_1 // PE.01 @@ -204,7 +240,7 @@ #define SWITCHES_GPIO_PIN_C_H GPIO_Pin_13 // PF.13 #define SWITCHES_GPIO_REG_C_L GPIOF->IDR #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_14 // PF.14 -#elif defined(PCBXLITE) +#elif defined(PCBXLITE) || defined(PCBX3) #define SWITCHES_GPIO_REG_C_L GPIOE->IDR #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_2 // PE.02 #define SWITCHES_GPIO_REG_C_H GPIOE->IDR @@ -241,6 +277,8 @@ #define SWITCHES_GPIO_PIN_D_L GPIO_Pin_1 // PE.01 #define SWITCHES_GPIO_REG_D_H GPIOE->IDR #define SWITCHES_GPIO_PIN_D_H GPIO_Pin_2 // PE.02 +#elif defined(PCBX3) + // no SWD #else #define SWITCHES_GPIO_REG_D_H GPIOE->IDR #define SWITCHES_GPIO_PIN_D_H GPIO_Pin_7 // PE.07 @@ -253,6 +291,12 @@ #define SWITCHES_GPIO_PIN_E_H GPIO_Pin_7 // PE.07 #define SWITCHES_GPIO_REG_E_L GPIOE->IDR #define SWITCHES_GPIO_PIN_E_L GPIO_Pin_13 // PE.13 +#elif defined(PCBXLITES) + #define SWITCHES_GPIO_REG_E GPIOE->IDR + #define SWITCHES_GPIO_PIN_E GPIO_Pin_5 // PE.05 +#elif defined(PCBX3) + #define SWITCHES_GPIO_REG_E GPIOC->IDR + #define SWITCHES_GPIO_PIN_E GPIO_Pin_13 // PC.13 #elif defined(PCBX7) || defined(PCBXLITE) // no SWE #else @@ -265,11 +309,17 @@ #if defined(PCBX9E) #define SWITCHES_GPIO_REG_F GPIOE->IDR #define SWITCHES_GPIO_PIN_F GPIO_Pin_11 // PE.11 +#elif defined(PCBXLITES) + #define SWITCHES_GPIO_REG_F GPIOC->IDR + #define SWITCHES_GPIO_PIN_F GPIO_Pin_3 // PC.03 #elif defined(PCBXLITE) // no SWF #elif defined(PCBX7) #define SWITCHES_GPIO_REG_F GPIOE->IDR #define SWITCHES_GPIO_PIN_F GPIO_Pin_14 // PE.14 +#elif defined(PCBX3) + #define SWITCHES_GPIO_REG_F GPIOA->IDR + #define SWITCHES_GPIO_PIN_F GPIO_Pin_5 // PA.05 #else #define SWITCHES_GPIO_REG_F GPIOE->IDR #define SWITCHES_GPIO_PIN_F GPIO_Pin_14 // PE.14 @@ -280,7 +330,7 @@ #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(PCBX7) || defined(PCBXLITE) +#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) // no SWG #else #define SWITCHES_GPIO_REG_G_H GPIOE->IDR @@ -295,7 +345,7 @@ #elif defined(PCBX9DP) #define SWITCHES_GPIO_REG_H GPIOD->IDR #define SWITCHES_GPIO_PIN_H GPIO_Pin_14 // PD.14 -#elif defined(PCBXLITE) +#elif defined(PCBXLITE) || defined(PCBX3) // no SWH #elif defined(PCBX7) #define SWITCHES_GPIO_REG_H GPIOD->IDR @@ -364,6 +414,12 @@ #define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_RHR) #define KEYS_GPIOD_PINS (KEYS_GPIO_PIN_MENU | KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_PAGE | SWITCHES_GPIO_PIN_H) #define KEYS_GPIOE_PINS (KEYS_GPIO_PIN_PLUS | KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_MINUS | TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_F | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L) +#elif defined(PCBXLITES) + #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE) + #define KEYS_GPIOA_PINS (GPIO_Pin_5 | GPIO_Pin_6) + #define KEYS_GPIOB_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5) + #define KEYS_GPIOC_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5) + #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14) #elif defined(PCBXLITE) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS (GPIO_Pin_5 | GPIO_Pin_6) @@ -371,11 +427,18 @@ #define KEYS_GPIOC_PINS (GPIO_Pin_4 | GPIO_Pin_5) #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14) #elif defined(PCBX7) - #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE) + #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS SWITCHES_GPIO_PIN_B_H #define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU) #define KEYS_GPIOD_PINS (TRIMS_GPIO_PIN_LHL | KEYS_GPIO_PIN_MENU | KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_PAGE | SWITCHES_GPIO_PIN_C_L | SWITCHES_GPIO_PIN_H) #define KEYS_GPIOE_PINS (ENC_GPIO_PIN_A | ENC_GPIO_PIN_B | KEYS_GPIO_PIN_ENTER | TRIMS_GPIO_PIN_RHR | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_A_H | SWITCHES_GPIO_PIN_F) +#elif defined(PCBX3) + #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_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_11 | GPIO_Pin_13 | GPIO_Pin_14) #else #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS (SWITCHES_GPIO_PIN_C_L) @@ -393,6 +456,7 @@ #define ADC_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) #define ADC_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) #define ADC_SAMPTIME 2 // sample time = 28 cycles +#define ADC_CHANNEL_RTC ADC_Channel_18 // ADC1_IN18 #if defined(PCBX9E) #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA2) #define ADC_RCC_APB1Periph 0 @@ -507,6 +571,24 @@ #define ADC_CHANNEL_POT1 ADC_Channel_6 #define ADC_CHANNEL_POT2 ADC_Channel_8 #define ADC_CHANNEL_BATT ADC_Channel_10 +#elif defined(PCBX3) + #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) + #define ADC_RCC_APB1Periph 0 + #define ADC_RCC_APB2Periph RCC_APB2Periph_ADC1 + #define ADC_GPIO_PIN_STICK_LH GPIO_Pin_0 // PA.00 + #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_1 // PA.01 + #define ADC_GPIO_PIN_STICK_RV GPIO_Pin_2 // PA.02 + #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_3 // PA.03 + #define ADC_CHANNEL_STICK_LH ADC_Channel_0 // ADC1_IN0 + #define ADC_CHANNEL_STICK_LV ADC_Channel_1 // ADC1_IN1 + #define ADC_CHANNEL_STICK_RV ADC_Channel_2 // ADC1_IN2 + #define ADC_CHANNEL_STICK_RH ADC_Channel_3 // ADC1_IN3 + #define ADC_GPIO_PIN_POT1 GPIO_Pin_1 // PC.01 + #define ADC_GPIO_PIN_BATT GPIO_Pin_0 // PC.00 + #define ADC_GPIOA_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3) + #define ADC_GPIOC_PINS (GPIO_Pin_0 | GPIO_Pin_1) + #define ADC_CHANNEL_POT1 ADC_Channel_11 // ADC1_IN11 + #define ADC_CHANNEL_BATT ADC_Channel_10 // ADC1_IN10 #else #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) #define ADC_RCC_APB1Periph 0 @@ -536,9 +618,14 @@ #endif // PWR and LED driver -#define PWR_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) +#define PWR_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) -#if defined(PCBXLITE) +#if defined(PCBX3) + #define PWR_SWITCH_GPIO GPIOA + #define PWR_SWITCH_GPIO_PIN GPIO_Pin_7 // PA.07 + #define PWR_ON_GPIO GPIOA + #define PWR_ON_GPIO_PIN GPIO_Pin_6 // PA.06 +#elif defined(PCBXLITE) #define PWR_SWITCH_GPIO GPIOA #define PWR_SWITCH_GPIO_PIN GPIO_Pin_7 // PA.07 #define PWR_ON_GPIO GPIOE @@ -549,8 +636,6 @@ #define PWR_ON_GPIO GPIOD #define PWR_ON_GPIO_PIN GPIO_Pin_0 // PD.00 #endif -#define PWR_ON_GPIO_MODER GPIO_MODER_MODER0 -#define PWR_ON_GPIO_MODER_OUT GPIO_MODER_MODER0_0 #if defined(PCBXLITE) #define STATUS_LEDS @@ -572,33 +657,50 @@ #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(PCBX3) + #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_GREEN_GPIO GPIOE + #define LED_GREEN_GPIO_PIN GPIO_Pin_4 // PE.04 + #define LED_BLUE_GPIO GPIOE + #define LED_BLUE_GPIO_PIN GPIO_Pin_6 // PE.06 #endif // Internal Module -#if defined(PCBXLITE) - #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) +#define HARDWARE_INTERNAL_MODULE +#if defined(PCBXLITE) || defined(PCBX3) #define INTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM3 #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1 - #define INTMODULE_PWR_GPIO GPIOD - #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_9 // PD.09 - #define INTMODULE_TX_GPIO GPIOB + #if defined(PCBXLITES) || defined(PCBX3) + #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_15 // PA.15 + #else + #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) + #define INTMODULE_PWR_GPIO GPIOD + #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_9 // PD.09 + #endif + #define INTMODULE_GPIO GPIOB #define INTMODULE_TX_GPIO_PIN GPIO_Pin_6 // PB.06 - #define INTMODULE_RX_GPIO GPIOB #define INTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PB.07 - #define INTMODULE_TX_GPIO_PinSource GPIO_PinSource6 - #define INTMODULE_RX_GPIO_PinSource GPIO_PinSource7 + #define INTMODULE_GPIO_PinSource_TX GPIO_PinSource6 + #define INTMODULE_GPIO_PinSource_RX GPIO_PinSource7 #define INTMODULE_USART USART1 - #define INTMODULE_TX_GPIO_AF GPIO_AF_USART1 + #define INTMODULE_GPIO_AF GPIO_AF_USART1 + #define INTMODULE_USART_IRQHandler USART1_IRQHandler #define INTMODULE_USART_IRQn USART1_IRQn #define INTMODULE_DMA_STREAM DMA2_Stream7 - #define INTMODULE_DMA_STREAM_IRQ DMA2_Stream7_IRQn - #define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream7_IRQHandler + #define INTMODULE_DMA_STREAM_IRQ DMA2_Stream7_IRQn + #define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream7_IRQHandler #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF7 #define INTMODULE_DMA_CHANNEL DMA_Channel_4 - #define INTMODULE_TIMER TIM3 - #define INTMODULE_TIMER_IRQn TIM3_IRQn - #define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler - #define INTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + // #define INTMODULE_TIMER TIM3 + // #define INTMODULE_TIMER_IRQn TIM3_IRQn + // #define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler + // #define INTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) #elif defined(PCBX9E) || defined(PCBX9DP) || defined(PCBX7) #define INTMODULE_PULSES #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) @@ -643,14 +745,30 @@ // External Module #define EXTMODULE_PULSES -#if defined(PCBXLITE) - #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) + +#if defined(PCBXLITE) || defined(PCBX3) #define EXTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM8 | RCC_APB2Periph_USART6) - #define EXTMODULE_PWR_GPIO GPIOD - #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_11 // PD.11 + #if defined(PCBX3) + #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) + #define EXTMODULE_PWR_GPIO GPIOA + #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PA.08 + #define EXTERNAL_MODULE_ON() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define EXTERNAL_MODULE_OFF() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_RESET) + #else + #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) + #define EXTMODULE_PWR_GPIO GPIOD + #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_11 // PD.11 + #define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) + #endif #define EXTMODULE_TX_GPIO GPIOC + #define EXTMODULE_USART_GPIO GPIOC #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_6 // PC.06 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource6 + #define EXTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PC.07 + #define EXTMODULE_RX_GPIO_PinSource GPIO_PinSource7 #define EXTMODULE_TIMER TIM8 #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #define EXTMODULE_TIMER_CC_IRQn TIM8_CC_IRQn @@ -663,19 +781,22 @@ #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1 #define EXTMODULE_TIMER_OUTPUT_ENABLE TIM_CCER_CC1E #define EXTMODULE_TIMER_OUTPUT_POLARITY TIM_CCER_CC1P - #define EXTMODULE_USART_TX_GPIO_AF GPIO_AF_USART6 + #define EXTMODULE_USART_GPIO_AF GPIO_AF_USART6 #define EXTMODULE_USART USART6 #define EXTMODULE_USART_IRQn USART6_IRQn + #define EXTMODULE_USART_IRQHandler USART6_IRQHandler #define EXTMODULE_USART_DMA_CHANNEL DMA_Channel_5 #define EXTMODULE_USART_DMA_STREAM DMA2_Stream6 #define EXTMODULE_USART_DMA_STREAM_IRQn DMA2_Stream6_IRQn - #define EXTMODULE_USART_DMA_STREAM_IRQHandler DMA2_Stream6_IRQHandler - #define EXTMODULE_USART_DMA_FLAG_TC DMA_IT_TCIF6 #else + #define EXTMODULE_PULSES #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) #define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM8 #define EXTMODULE_PWR_GPIO GPIOD #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PD.08 + #define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) + #define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET) #define EXTMODULE_TX_GPIO GPIOA #define EXTMODULE_TX_GPIO_PIN GPIO_Pin_7 // PA.07 #define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource7 @@ -687,18 +808,49 @@ #define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream1 #define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream1_IRQn #define EXTMODULE_TIMER_DMA_STREAM_IRQHandler DMA2_Stream1_IRQHandler - #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1 + #define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1 #define EXTMODULE_TIMER_OUTPUT_ENABLE TIM_CCER_CC1NE #define EXTMODULE_TIMER_OUTPUT_POLARITY TIM_CCER_CC1NP - #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) + #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #endif // Trainer Port -#if defined(PCBXLITE) +#if defined(PCBXLITES) || defined(PCBX3) + // on these 2 radios the trainer port already uses DMA1_Stream6, we won't use the DMA + #define TRAINER_RCC_AHB1Periph RCC_AHB1Periph_GPIOD + #define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM4 + #define TRAINER_GPIO GPIOD + #define TRAINER_IN_GPIO_PIN GPIO_Pin_13 // PD.13 + #define TRAINER_IN_GPIO_PinSource GPIO_PinSource13 + #define TRAINER_OUT_GPIO_PIN GPIO_Pin_12 // PD.12 + #define TRAINER_OUT_GPIO_PinSource GPIO_PinSource12 +#if defined(PCBX3) + #define TRAINER_DETECT_GPIO GPIOD + #define TRAINER_DETECT_GPIO_PIN GPIO_Pin_11 // PD.11 +#endif + #define TRAINER_TIMER TIM4 + #define TRAINER_TIMER_IRQn TIM4_IRQn + #define TRAINER_GPIO_AF GPIO_AF_TIM4 // TIM4_CH1 (Out) + TIM4_CH2 (In) + #define TRAINER_TIMER_IRQn TIM4_IRQn + #define TRAINER_TIMER_IRQHandler TIM4_IRQHandler + #define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + #define TRAINER_OUT_CCMR1 TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE; + #define TRAINER_IN_CCMR1 TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0; + #define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR1 + #define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR2 + #define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR3 + #define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC3IF + #define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC3IE + #define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC2IE + #define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC2IF + #define TRAINER_OUT_CCER TIM_CCER_CC1E + #define TRAINER_CCER_POLARYTY TIM_CCER_CC1P + #define TRAINER_IN_CCER TIM_CCER_CC2E +#elif defined(PCBXLITE) #define TRAINER_RCC_AHB1Periph 0 #define TRAINER_RCC_APB1Periph 0 #else - #define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC) + #define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA1) #define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM3 #define TRAINER_GPIO GPIOC #define TRAINER_IN_GPIO_PIN GPIO_Pin_8 // PC.08 @@ -719,10 +871,22 @@ #define TRAINER_TIMER_IRQn TIM3_IRQn #define TRAINER_TIMER_IRQHandler TIM3_IRQHandler #define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + #define TRAINER_OUT_CCMR2 TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE; + #define TRAINER_IN_CCMR2 TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0; + #define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR4 + #define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR3 + #define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR1 + #define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC1IF + #define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC1IE + #define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC3IE + #define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC3IF + #define TRAINER_OUT_CCER TIM_CCER_CC4E + #define TRAINER_IN_CCER TIM_CCER_CC3E + #define TRAINER_CCER_POLARYTY TIM_CCER_CC4P #endif // Serial Port -#if defined(PCBX7) || defined(PCBXLITE) +#if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX3) #define SERIAL_RCC_AHB1Periph 0 #define SERIAL_RCC_APB1Periph 0 #else @@ -784,14 +948,21 @@ #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOD #define SPORT_UPDATE_PWR_GPIO GPIOD #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_8 // PD.08 - #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits + #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits #define GPIO_SPORT_UPDATE_PWR_GPIO_OFF GPIO_ResetBits #elif defined(PCBX7) #define SPORT_MAX_BAUDRATE 250000 // < 400000 #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define SPORT_UPDATE_PWR_GPIO GPIOB #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_2 // PB.02 - #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits + #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits + #define GPIO_SPORT_UPDATE_PWR_GPIO_OFF GPIO_ResetBits +#elif defined(PCBX3) + #define SPORT_MAX_BAUDRATE 250000 // not tested + #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOE + #define SPORT_UPDATE_PWR_GPIO GPIOE + #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_15 // PE.15 + #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits #define GPIO_SPORT_UPDATE_PWR_GPIO_OFF GPIO_ResetBits #else #define SPORT_MAX_BAUDRATE 400000 @@ -799,7 +970,7 @@ #endif // Heartbeat -#if defined(PCBXLITE) +#if defined(PCBXLITE) || defined(PCBX3) #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD #define HEARTBEAT_RCC_APB2Periph 0 #define HEARTBEAT_GPIO GPIOD @@ -857,6 +1028,19 @@ #define BACKLIGHT_GPIO_PinSource_2 GPIO_PinSource13 #define BACKLIGHT_GPIO_AF_1 GPIO_AF_TIM4 #define BACKLIGHT_GPIO_AF_2 GPIO_AF_TIM4 +#elif defined(PCBXLITES) || defined(PCBX3) + #define BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOA + #define BACKLIGHT_RCC_APB1Periph 0 + #define BACKLIGHT_RCC_APB2Periph RCC_APB2Periph_TIM1 + #define BACKLIGHT_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) + #define BACKLIGHT_TIMER TIM1 + #define BACKLIGHT_GPIO GPIOA + #define BACKLIGHT_GPIO_PIN GPIO_Pin_10 // PA.10 + #define BACKLIGHT_GPIO_PinSource GPIO_PinSource10 + #define BACKLIGHT_GPIO_AF GPIO_AF_TIM1 + #define BACKLIGHT_CCMR2 TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 // Channel 3, PWM + #define BACKLIGHT_CCER TIM_CCER_CC3E + #define BACKLIGHT_COUNTER_REGISTER BACKLIGHT_TIMER->CCR3 #elif defined(PCBXLITE) #define BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOA #define BACKLIGHT_RCC_APB1Periph 0 @@ -917,7 +1101,7 @@ #define LCD_DMA_FLAG_INT DMA_HIFCR_CTCIF7 #define LCD_SPI SPI3 #define LCD_GPIO_AF GPIO_AF_SPI3 -#elif defined(PCBXLITE) +#elif defined(PCBXLITE) || defined(PCBX3) #define LCD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define LCD_RCC_APB1Periph RCC_APB1Periph_SPI3 #define LCD_SPI_GPIO GPIOC @@ -977,7 +1161,7 @@ #define I2C_RCC_APB1Periph RCC_APB1Periph_I2C1 #define I2C I2C1 #define I2C_GPIO_AF GPIO_AF_I2C1 -#if defined(PCBXLITE) +#if defined(PCBXLITE) || defined(PCBX3) #define I2C_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD) #define I2C_SPI_GPIO GPIOB #define I2C_SDA_GPIO_PIN GPIO_Pin_9 // PB.09 @@ -1005,11 +1189,29 @@ #define I2C_ADDRESS_VOLUME 0x5C #define I2C_FLASH_PAGESIZE 64 +// Second I2C Bus: IMU +#if defined(PCBXLITES) + #define GYRO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC) + #define GYRO_RCC_APB1Periph RCC_APB1Periph_I2C3 + #define I2CX I2C3 + #define I2CX_SCL_GPIO GPIOA + #define I2CX_SCL_GPIO_PIN GPIO_Pin_8 // PA.08 + #define I2CX_SDA_GPIO GPIOC + #define I2CX_SDA_GPIO_PIN GPIO_Pin_9 // PC.09 + #define I2CX_GPIO_AF GPIO_AF_I2C3 + #define I2CX_SCL_GPIO_PinSource GPIO_PinSource8 + #define I2CX_SDA_GPIO_PinSource GPIO_PinSource9 + #define I2CX_SPEED 400000 +#else + #define GYRO_RCC_AHB1Periph 0 + #define GYRO_RCC_APB1Periph 0 +#endif + // SD - SPI2 #define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define SD_RCC_APB1Periph RCC_APB1Periph_SPI2 #define SD_GPIO_PRESENT_GPIO GPIOD -#if defined(PCBXLITE) +#if defined(PCBXLITE) || defined(PCBX3) #define SD_GPIO_PRESENT_GPIO_PIN GPIO_Pin_10 // PD.10 #else #define SD_GPIO_PRESENT_GPIO_PIN GPIO_Pin_9 // PD.09 @@ -1037,7 +1239,6 @@ #endif // Audio -#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1) #define AUDIO_RCC_APB1Periph (RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC) #define AUDIO_OUTPUT_GPIO GPIOA #define AUDIO_OUTPUT_GPIO_PIN GPIO_Pin_4 // PA.04 @@ -1049,8 +1250,20 @@ #define AUDIO_TIMER TIM6 #define AUDIO_DMA DMA1 +#if defined(PCBXLITES) + #define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) + #define JACK_DETECT_GPIO GPIOC + #define JACK_DETECT_GPIO_PIN GPIO_Pin_13 // PC.13 + #define AUDIO_SPEAKER_ENABLE_GPIO GPIOD + #define AUDIO_SPEAKER_ENABLE_GPIO_PIN GPIO_Pin_14 // PD.14 + #define HEADPHONE_TRAINER_SWITCH_GPIO GPIOD + #define HEADPHONE_TRAINER_SWITCH_GPIO_PIN GPIO_Pin_9 // PD.09 +#else + #define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1) +#endif + // Haptic -#if defined(PCBXLITE) +#if defined(PCBXLITE) || defined(PCBX3) #define HAPTIC_PWM #define HAPTIC_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define HAPTIC_RCC_APB1Periph RCC_APB1Periph_TIM2 @@ -1106,7 +1319,7 @@ #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG) #define BT_RCC_APB1Periph 0 #define BT_RCC_APB2Periph RCC_APB2Periph_USART6 - #define BT_GPIO_TXRX GPIOG + #define BT_USART_GPIO GPIOG #define BT_TX_GPIO_PIN GPIO_Pin_14 // PG.14 #define BT_RX_GPIO_PIN GPIO_Pin_9 // PG.09 #define BT_EN_GPIO GPIOD @@ -1119,7 +1332,7 @@ #define BT_RX_GPIO_PinSource GPIO_PinSource9 #define BT_USART_IRQHandler USART6_IRQHandler #elif defined(PCBX7) || defined(PCBXLITE) - #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA1) + #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE) // RCC_AHB1Periph_DMA1 #define BT_RCC_APB1Periph RCC_APB1Periph_USART3 #define BT_RCC_APB2Periph 0 #define BT_EN_GPIO GPIOE @@ -1128,7 +1341,7 @@ #else #define BT_EN_GPIO_PIN GPIO_Pin_12 // PE.12 #endif - #define BT_GPIO_TXRX GPIOB + #define BT_USART_GPIO GPIOB #define BT_TX_GPIO_PIN GPIO_Pin_10 // PB.10 #define BT_RX_GPIO_PIN GPIO_Pin_11 // PB.11 #define BT_TX_GPIO_PinSource GPIO_PinSource10 @@ -1137,8 +1350,8 @@ #define BT_USART USART3 #define BT_USART_IRQHandler USART3_IRQHandler #define BT_USART_IRQn USART3_IRQn - #define BT_DMA_Stream_RX DMA1_Stream1 - #define BT_DMA_Channel_RX DMA_Channel_4 + // #define BT_DMA_Stream_RX DMA1_Stream1 + // #define BT_DMA_Channel_RX DMA_Channel_4 #else #define BT_RCC_AHB1Periph 0 #define BT_RCC_APB1Periph 0 diff --git a/radio/src/targets/taranis/i2c_driver.cpp b/radio/src/targets/taranis/i2c_driver.cpp index 65138b7eb..2620312ba 100644 --- a/radio/src/targets/taranis/i2c_driver.cpp +++ b/radio/src/targets/taranis/i2c_driver.cpp @@ -179,7 +179,7 @@ uint8_t eepromIsTransferComplete() * @param NumByteToWrite : number of bytes to write to the EEPROM. * @retval None */ -bool I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) +bool I2C_EE_PageWrite(uint8_t * pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) { if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) return false; diff --git a/radio/src/targets/taranis/intmodule_pulses_driver.cpp b/radio/src/targets/taranis/intmodule_pulses_driver.cpp index 1999dc796..719c0ff21 100644 --- a/radio/src/targets/taranis/intmodule_pulses_driver.cpp +++ b/radio/src/targets/taranis/intmodule_pulses_driver.cpp @@ -32,61 +32,46 @@ void intmoduleStop() INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; } -void intmoduleNoneStart() -{ - INTERNAL_MODULE_OFF(); - - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(INTMODULE_TX_GPIO, &GPIO_InitStructure); - GPIO_SetBits(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PIN); // Set high - - INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; - INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz - INTMODULE_TIMER->ARR = 36000; // 18mS - INTMODULE_TIMER->CCR2 = 32000; // Update time - INTMODULE_TIMER->EGR = 1; // Restart - 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_CC_IRQn); - NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7); -} - void intmoduleSendNextFrame() { - if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) { - INTMODULE_TIMER->CCR2 = modulePulsesData[INTERNAL_MODULE].pxx.getLast() - 4000; // 2mS in advance - INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR); - INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].pxx.getData()); - INTMODULE_DMA_STREAM->NDTR = modulePulsesData[INTERNAL_MODULE].pxx.getSize(); - INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } -#if defined(TARANIS_INTERNAL_PPM) - else if (s_current_protocol[INTERNAL_MODULE] == PROTO_PPM) { - INTMODULE_TIMER->CCR3 = GET_PPM_DELAY(INTERNAL_MODULE)*2; - INTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_PPM_POLARITY(INTERNAL_MODULE) ? 0 : TIM_CCER_CC3P); - INTMODULE_TIMER->CCR2 = *(modulePulsesData[INTERNAL_MODULE].ppm.ptr - 1) - 4000; // 2mS in advance - INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA - INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; - INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR); - INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].ppm.pulses); - INTMODULE_DMA_STREAM->NDTR = modulePulsesData[INTERNAL_MODULE].ppm.ptr - modulePulsesData[INTERNAL_MODULE].ppm.pulses; - INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA - } + switch (moduleSettings[INTERNAL_MODULE].protocol) { +#if defined(PXX1) + case PROTOCOL_CHANNELS_PXX1_PULSES: + INTMODULE_TIMER->CCR2 = intmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance + INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR); + INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(intmodulePulsesData.pxx.getData()); + INTMODULE_DMA_STREAM->NDTR = intmodulePulsesData.pxx.getSize(); + INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; #endif - else { - INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + +#if defined(TARANIS_INTERNAL_PPM) + case PROTOCOL_CHANNELS_PPM: + INTMODULE_TIMER->CCR3 = GET_MODULE_PPM_DELAY(INTERNAL_MODULE) * 2; + INTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_MODULE_PPM_POLARITY(INTERNAL_MODULE) ? 0 : TIM_CCER_CC3P); + INTMODULE_TIMER->CCR2 = *(intmodulePulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA + INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR); + INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(intmodulePulsesData.ppm.pulses); + INTMODULE_DMA_STREAM->NDTR = intmodulePulsesData.ppm.ptr - intmodulePulsesData.ppm.pulses; + INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA + break; +#endif + + default: + INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; + break; } } +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable) +{ + // nothing, the pulses will be sent through telemetry port +} + void intmodulePxxStart() { INTERNAL_MODULE_ON(); @@ -111,10 +96,11 @@ void intmodulePxxStart() INTMODULE_TIMER->EGR = 1; // Restart INTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; + INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + INTMODULE_TIMER->CCR2 = 16000; // The first frame will be sent in 20ms + INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt INTMODULE_TIMER->CR1 |= TIM_CR1_CEN; - intmoduleSendNextFrame(); - NVIC_EnableIRQ(INTMODULE_DMA_STREAM_IRQn); NVIC_SetPriority(INTMODULE_DMA_STREAM_IRQn, 7); NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn); @@ -143,10 +129,11 @@ void intmodulePpmStart() INTMODULE_TIMER->BDTR = TIM_BDTR_MOE; INTMODULE_TIMER->EGR = 1; INTMODULE_TIMER->DIER = TIM_DIER_UDE; + INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + INTMODULE_TIMER->CCR2 = 40000; // The first frame will be sent in 20ms + INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt INTMODULE_TIMER->CR1 = TIM_CR1_CEN; - intmoduleSendNextFrame(); - NVIC_EnableIRQ(INTMODULE_DMA_STREAM_IRQn); NVIC_SetPriority(INTMODULE_DMA_STREAM_IRQn, 7); NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn); @@ -169,6 +156,7 @@ extern "C" void INTMODULE_TIMER_CC_IRQHandler() { INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; - setupPulses(INTERNAL_MODULE); - intmoduleSendNextFrame(); + if (setupPulses(INTERNAL_MODULE)) { + intmoduleSendNextFrame(); + } } diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp index 1f44b824f..b4a061d6f 100644 --- a/radio/src/targets/taranis/keys_driver.cpp +++ b/radio/src/targets/taranis/keys_driver.cpp @@ -207,9 +207,15 @@ uint32_t switchState(uint8_t index) ADD_3POS_CASE(A, 0); ADD_3POS_CASE(B, 1); ADD_3POS_CASE(C, 2); +#if !defined(PCBX3) ADD_3POS_CASE(D, 3); -#if defined(PCBXLITE) - // no SWF, SWG and SWH on XLITE +#endif +#if defined(PCBXLITES) || defined(PCBX3) + ADD_2POS_CASE(E); + ADD_2POS_CASE(F); + // no SWG and SWH on XLITES and X3 +#elif defined(PCBXLITE) || defined(PCBX3) + // no SWE, SWF, SWG and SWH on X3 and XLITE #elif defined(PCBX7) ADD_2POS_CASE(F); ADD_2POS_CASE(H); diff --git a/radio/src/targets/taranis/pulses_driver.cpp b/radio/src/targets/taranis/pulses_driver.cpp index 9b7cfea4d..fd5853856 100644 --- a/radio/src/targets/taranis/pulses_driver.cpp +++ b/radio/src/targets/taranis/pulses_driver.cpp @@ -20,103 +20,94 @@ #include "opentx.h" -void intmoduleStop(void); -void extmoduleStop(void); - -void intmoduleNoneStart(void); -void intmodulePxxStart(void); -#if defined(TARANIS_INTERNAL_PPM) -void intmodulePpmStart(void); -#endif - -void extmoduleTimerStart(uint32_t period, uint8_t state); -void extmodulePpmStart(void); -void extmodulePxxStart(void); -void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us); - - -void init_pxx(uint32_t port) +#if defined(PXX1) +void init_pxx1_pulses(uint8_t module) { - if (port == INTERNAL_MODULE) + if (module == INTERNAL_MODULE) intmodulePxxStart(); else - extmodulePxxStart(); + extmodulePxxPulsesStart(); } -void disable_pxx(uint32_t port) +void init_pxx1_serial(uint8_t module) { - if (port == INTERNAL_MODULE) + if (module == INTERNAL_MODULE) + intmodulePxxStart(); +#if defined(EXTMODULE_USART) + else + extmodulePxxSerialStart(); +#endif +} + +void disable_pxx1_pulses(uint8_t module) +{ + if (module == INTERNAL_MODULE) + intmoduleStop(); + else + extmoduleStop(); +} + +void disable_pxx1_serial(uint8_t module) +{ + if (module == INTERNAL_MODULE) + intmoduleStop(); + else + extmoduleStop(); +} +#endif + +void init_pxx2(uint8_t module) +{ + if (module == INTERNAL_MODULE) + intmoduleSerialStart(INTMODULE_PXX_BAUDRATE, true); + else + extmodulePxx2Start(); +} + +void disable_pxx2(uint8_t module) +{ + if (module == INTERNAL_MODULE) intmoduleStop(); else extmoduleStop(); } #if defined(DSM2) -void init_serial(uint32_t port, uint32_t baudrate, uint32_t period_half_us) +void init_serial(uint8_t module, uint32_t baudrate, uint32_t period_half_us) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmoduleSerialStart(baudrate, period_half_us); } } -void disable_serial(uint32_t port) +void disable_serial(uint8_t module) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmoduleStop(); } } #endif -void init_ppm(uint32_t port) +void init_ppm(uint8_t module) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmodulePpmStart(); } #if defined(TARANIS_INTERNAL_PPM) - else if (port == INTERNAL_MODULE) { + else { intmodulePpmStart(); } #endif } -void disable_ppm(uint32_t port) +void disable_ppm(uint8_t module) { - if (port == EXTERNAL_MODULE) { + if (module == EXTERNAL_MODULE) { extmoduleStop(); } #if defined(TARANIS_INTERNAL_PPM) - else if (port == INTERNAL_MODULE) { + else { intmoduleStop(); } #endif } - -void init_no_pulses(uint32_t port) -{ - if (port == INTERNAL_MODULE) - intmoduleNoneStart(); - else - extmoduleTimerStart(18, false); -} - -void disable_no_pulses(uint32_t port) -{ - if (port == INTERNAL_MODULE) - intmoduleStop(); - else - extmoduleStop(); -} - -void init_module_timer(uint32_t port, uint32_t period, uint8_t state) -{ - if (port == EXTERNAL_MODULE) { - extmoduleTimerStart(period, state); - } -} - -void disable_module_timer(uint32_t port) -{ - if (port == EXTERNAL_MODULE) { - extmoduleStop(); - } -} diff --git a/radio/src/targets/taranis/pwr_driver.cpp b/radio/src/targets/taranis/pwr_driver.cpp index d754d3473..f233eaaac 100644 --- a/radio/src/targets/taranis/pwr_driver.cpp +++ b/radio/src/targets/taranis/pwr_driver.cpp @@ -32,8 +32,8 @@ void pwrInit() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN); GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN; GPIO_Init(INTMODULE_PWR_GPIO, &GPIO_InitStructure); - - GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN); + + EXTERNAL_MODULE_OFF(); GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_GPIO_PIN; GPIO_Init(EXTMODULE_PWR_GPIO, &GPIO_InitStructure); diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index f3b58159e..31c632c05 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -37,12 +37,10 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - USART_InitTypeDef USART_InitStructure; - GPIO_InitTypeDef GPIO_InitStructure; - - GPIO_PinAFConfig(TELEMETRY_GPIO, TELEMETRY_GPIO_PinSource_RX, TELEMETRY_GPIO_AF); GPIO_PinAFConfig(TELEMETRY_GPIO, TELEMETRY_GPIO_PinSource_TX, TELEMETRY_GPIO_AF); + GPIO_PinAFConfig(TELEMETRY_GPIO, TELEMETRY_GPIO_PinSource_RX, TELEMETRY_GPIO_AF); + GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = TELEMETRY_TX_GPIO_PIN | TELEMETRY_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; @@ -56,6 +54,8 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure); TELEMETRY_DIR_INPUT(); + USART_DeInit(TELEMETRY_USART); + USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = baudrate; if (mode & TELEMETRY_SERIAL_8E2) { USART_InitStructure.USART_WordLength = USART_WordLength_9b; @@ -70,8 +70,8 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(TELEMETRY_USART, &USART_InitStructure); - USART_Cmd(TELEMETRY_USART, ENABLE); + USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE); NVIC_SetPriority(TELEMETRY_USART_IRQn, 6); NVIC_EnableIRQ(TELEMETRY_USART_IRQn); @@ -127,9 +127,8 @@ extern "C" void TELEMETRY_DMA_TX_IRQHandler(void) if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) { DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC); TELEMETRY_USART->CR1 |= USART_CR1_TCIE; - if (telemetryProtocol == PROTOCOL_FRSKY_SPORT) { - outputTelemetryBufferSize = 0; - outputTelemetryBufferTrigger = 0x7E; + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || telemetryProtocol == PROTOCOL_TELEMETRY_PXX2) { + outputTelemetryBuffer.reset(); } } } @@ -157,10 +156,10 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) else { telemetryFifo.push(data); #if defined(LUA) - if (telemetryProtocol == PROTOCOL_FRSKY_SPORT) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) { static uint8_t prevdata; - if (prevdata == 0x7E && outputTelemetryBufferSize > 0 && data == outputTelemetryBufferTrigger) { - sportSendBuffer(outputTelemetryBuffer, outputTelemetryBufferSize); + if (prevdata == 0x7E && outputTelemetryBuffer.size > 0 && data == outputTelemetryBuffer.trigger && outputTelemetryBuffer.destination == SPORT_MODULE) { + sportSendBuffer(outputTelemetryBuffer.data, outputTelemetryBuffer.size); } prevdata = data; } @@ -174,7 +173,7 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) uint8_t telemetryGetByte(uint8_t * byte) { #if defined(SERIAL2) - if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { if (serial2Mode == UART_MODE_TELEMETRY) return serial2RxFifo.pop(*byte); else diff --git a/radio/src/targets/taranis/top_lcd_driver.cpp b/radio/src/targets/taranis/top_lcd_driver.cpp index e0bf2f467..743d0784d 100644 --- a/radio/src/targets/taranis/top_lcd_driver.cpp +++ b/radio/src/targets/taranis/top_lcd_driver.cpp @@ -374,7 +374,7 @@ void setTopSecondTimer(uint32_t value) uint32_t secs = qr.rem; qr = div(qr.quot, 60); uint32_t mins = qr.rem; - uint32_t hours = qr.quot; + uint32_t hours = min(qr.quot, 99); qr = div(secs, 10); segs = OpTimeLCDsegs[qr.rem]; diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp index 1992d635e..000c0721b 100644 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ b/radio/src/targets/taranis/trainer_driver.cpp @@ -20,7 +20,9 @@ #include "opentx.h" +#if defined(HEARTBEAT_USART) DMAFifo<32> heartbeatFifo __DMA (HEARTBEAT_DMA_Stream); +#endif void trainerSendNextFrame(); @@ -39,7 +41,11 @@ void init_trainer_ppm() TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS TRAINER_TIMER->ARR = 45000; - TRAINER_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE; // PWM mode 1 +#if defined(TRAINER_OUT_CCMR1) + TRAINER_TIMER->CCMR1 = TRAINER_OUT_CCMR1; +#elif defined(TRAINER_OUT_CCMR2) + TRAINER_TIMER->CCMR2 = TRAINER_OUT_CCMR2; +#endif TRAINER_TIMER->BDTR = TIM_BDTR_MOE; TRAINER_TIMER->EGR = 1; TRAINER_TIMER->DIER |= TIM_DIER_UDE; @@ -48,18 +54,23 @@ void init_trainer_ppm() setupPulsesPPMTrainer(); trainerSendNextFrame(); +#if defined(TRAINER_DMA_STREAM) NVIC_EnableIRQ(TRAINER_DMA_IRQn); NVIC_SetPriority(TRAINER_DMA_IRQn, 7); +#endif + NVIC_EnableIRQ(TRAINER_TIMER_IRQn); NVIC_SetPriority(TRAINER_TIMER_IRQn, 7); } void stop_trainer_ppm() { +#if defined(TRAINER_DMA_STREAM) NVIC_DisableIRQ(TRAINER_DMA_IRQn); - NVIC_DisableIRQ(TRAINER_TIMER_IRQn); - TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA +#endif + + NVIC_DisableIRQ(TRAINER_TIMER_IRQn); TRAINER_TIMER->DIER = 0; TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter } @@ -79,10 +90,14 @@ void init_trainer_capture() TRAINER_TIMER->ARR = 0xFFFF; TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS TRAINER_TIMER->CR2 = 0; - TRAINER_TIMER->CCMR2 = TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0; - TRAINER_TIMER->CCER = TIM_CCER_CC3E; +#if defined(TRAINER_IN_CCMR1) + TRAINER_TIMER->CCMR1 = TRAINER_IN_CCMR1; +#elif defined(TRAINER_IN_CCMR2) + TRAINER_TIMER->CCMR2 = TRAINER_IN_CCMR2; +#endif + TRAINER_TIMER->CCER = TRAINER_IN_CCER; TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags - TRAINER_TIMER->DIER |= TIM_DIER_CC3IE; + TRAINER_TIMER->DIER |= TRAINER_IN_INTERRUPT_ENABLE; TRAINER_TIMER->CR1 = TIM_CR1_CEN; NVIC_EnableIRQ(TRAINER_TIMER_IRQn); @@ -98,18 +113,26 @@ void stop_trainer_capture() void trainerSendNextFrame() { - TRAINER_TIMER->CCR4 = GET_PPM_DELAY(TRAINER_MODULE)*2; - TRAINER_TIMER->CCER = TIM_CCER_CC4E | (GET_PPM_POLARITY(TRAINER_MODULE) ? 0 : TIM_CCER_CC4P); - TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + TRAINER_OUT_COUNTER_REGISTER = GET_TRAINER_PPM_DELAY() * 2; + TRAINER_TIMER->CCER = TRAINER_OUT_CCER | (GET_TRAINER_PPM_POLARITY() ? 0 : TRAINER_CCER_POLARYTY); + TRAINER_SETUP_REGISTER = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance +#if defined(TRAINER_DMA_STREAM) TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA TRAINER_DMA_STREAM->CR |= TRAINER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; TRAINER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&TRAINER_TIMER->ARR); TRAINER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(trainerPulsesData.ppm.pulses); TRAINER_DMA_STREAM->NDTR = trainerPulsesData.ppm.ptr - trainerPulsesData.ppm.pulses; TRAINER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA +#else + trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses; + TRAINER_TIMER->DIER |= TIM_DIER_UDE; + TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag + TRAINER_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt +#endif } +#if defined(TRAINER_DMA_STREAM) extern "C" void TRAINER_DMA_IRQHandler() { if (!DMA_GetITStatus(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC)) @@ -117,9 +140,10 @@ extern "C" void TRAINER_DMA_IRQHandler() DMA_ClearITPendingBit(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC); - TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag - TRAINER_TIMER->DIER |= TIM_DIER_CC1IE; // Enable this interrupt + TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag + TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt } +#endif extern "C" void TRAINER_TIMER_IRQHandler() { @@ -129,14 +153,15 @@ extern "C" void TRAINER_TIMER_IRQHandler() bool doCapture = false; // What mode? in or out? - if ((TRAINER_TIMER->DIER & TIM_DIER_CC3IE) && (TRAINER_TIMER->SR & TIM_SR_CC3IF)) { + if ((TRAINER_TIMER->DIER & TRAINER_IN_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_IN_INTERRUPT_FLAG)) { // capture mode on trainer jack - capture = TRAINER_TIMER->CCR3; + capture = TRAINER_IN_COUNTER_REGISTER; if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) { doCapture = true; } } +#if defined(TRAINER_MODULE_HEARTBEAT) if ((TRAINER_TIMER->DIER & TIM_DIER_CC2IE) && (TRAINER_TIMER->SR & TIM_SR_CC2IF)) { // capture mode on heartbeat pin (external module) capture = TRAINER_TIMER->CCR2; @@ -144,22 +169,36 @@ extern "C" void TRAINER_TIMER_IRQHandler() doCapture = true; } } +#endif if (doCapture) { captureTrainerPulses(capture); } // PPM out compare interrupt - if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) { + if ((TRAINER_TIMER->DIER & TRAINER_OUT_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_OUT_INTERRUPT_FLAG)) { // compare interrupt - TRAINER_TIMER->DIER &= ~TIM_DIER_CC1IE; // stop this interrupt - TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag + TRAINER_TIMER->DIER &= ~TRAINER_OUT_INTERRUPT_ENABLE; // stop this interrupt + TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag setupPulsesPPMTrainer(); trainerSendNextFrame(); } + +#if !defined(TRAINER_DMA_STREAM) + // PPM out update interrupt + if ((TRAINER_TIMER->DIER & TIM_DIER_UIE) && (TRAINER_TIMER->SR & TIM_SR_UIF)) { + TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear flag + TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++; + if (*trainerPulsesData.ppm.ptr == 0) { + TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear this flag + TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt + } + } +#endif } -void init_cppm_on_heartbeat_capture(void) +#if defined(TRAINER_MODULE_HEARTBEAT) +void init_cppm_on_heartbeat_capture() { EXTERNAL_MODULE_ON(); @@ -196,7 +235,9 @@ void stop_cppm_on_heartbeat_capture() EXTERNAL_MODULE_OFF(); } } +#endif +#if defined(HEARTBEAT_USART) void init_sbus_on_heartbeat_capture() { EXTERNAL_MODULE_ON(); @@ -258,13 +299,16 @@ void stop_sbus_on_heartbeat_capture() EXTERNAL_MODULE_OFF(); } } +#endif int sbusGetByte(uint8_t * byte) { switch (currentTrainerMode) { +#if defined(HEARTBEAT_USART) case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: return heartbeatFifo.pop(*byte); -#if !defined(PCBX7) && !defined(PCBX9E) +#endif +#if !defined(PCBX7) && !defined(PCBX9E) && !defined(PCBX3) && !defined(PCBXLITE) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: return serial2RxFifo.pop(*byte); #endif diff --git a/radio/src/tasks_arm.cpp b/radio/src/tasks.cpp similarity index 77% rename from radio/src/tasks_arm.cpp rename to radio/src/tasks.cpp index fecc02333..2c787860b 100644 --- a/radio/src/tasks_arm.cpp +++ b/radio/src/tasks.cpp @@ -73,6 +73,32 @@ bool isForcePowerOffRequested() return false; } +bool isModuleSynchronous(uint8_t module) +{ + uint8_t protocol = moduleSettings[module].protocol; + if (protocol == PROTOCOL_CHANNELS_PXX2 || protocol == PROTOCOL_CHANNELS_CROSSFIRE || protocol == PROTOCOL_CHANNELS_NONE) + return true; +#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) + if (protocol == PROTOCOL_CHANNELS_PXX1_SERIAL) + return true; +#endif + return false; +} + +void sendSynchronousPulses() +{ + for (uint8_t module = 0; module < NUM_MODULES; module++) { + if (isModuleSynchronous(module) && setupPulses(module)) { +#if defined(HARDWARE_INTERNAL_MODULE) + if (module == INTERNAL_MODULE) + intmoduleSendNextFrame(); +#endif + if (module == EXTERNAL_MODULE) + extmoduleSendNextFrame(); + } + } +} + uint32_t nextMixerTime[NUM_MODULES]; TASK_FUNCTION(mixerTask) @@ -82,15 +108,17 @@ TASK_FUNCTION(mixerTask) while(1) { -#if defined(SBUS) +#if defined(PCBX9D) || defined(PCBX7) + // SBUS on Hearbeat PIN (which is a serial RX) processSbusInput(); #endif RTOS_WAIT_TICKS(1); #if defined(SIMU) - if (pwrCheck() == e_power_off) + if (pwrCheck() == e_power_off) { TASK_RETURN(); + } #else if (isForcePowerOffRequested()) { pwrOff(); @@ -153,7 +181,9 @@ TASK_FUNCTION(mixerTask) } t0 = getTmr2MHz() - t0; - if (t0 > maxMixerDuration) maxMixerDuration = t0 ; + if (t0 > maxMixerDuration) maxMixerDuration = t0; + + sendSynchronousPulses(); } } } @@ -161,12 +191,23 @@ TASK_FUNCTION(mixerTask) void scheduleNextMixerCalculation(uint8_t module, uint16_t period_ms) { // Schedule next mixer calculation time, - // for now assume mixer calculation takes 2 ms. - nextMixerTime[module] = (uint32_t)RTOS_GET_TIME() + period_ms / 2 - 1/*2ms*/; + + if (isModuleSynchronous(module)) { + nextMixerTime[module] += period_ms / RTOS_MS_PER_TICK; + if (nextMixerTime[module] < RTOS_GET_TIME()) { + // we are late ... let's add some small delay + nextMixerTime[module] = (uint32_t) RTOS_GET_TIME() + (period_ms / RTOS_MS_PER_TICK); + } + } + else { + // for now assume mixer calculation takes 2 ms. + nextMixerTime[module] = (uint32_t) RTOS_GET_TIME() + (period_ms / RTOS_MS_PER_TICK) - 1 /* 1 tick in advance*/; + } + DEBUG_TIMER_STOP(debugTimerMixerCalcToUsage); } -#define MENU_TASK_PERIOD_TICKS 25 // 50ms +#define MENU_TASK_PERIOD_TICKS (50 / RTOS_MS_PER_TICK) // 50ms #if defined(COLORLCD) && defined(CLI) bool perMainEnabled = true; diff --git a/radio/src/tasks_arm.h b/radio/src/tasks.h similarity index 100% rename from radio/src/tasks_arm.h rename to radio/src/tasks.h diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index b80ebdf36..d0f2652ad 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -21,6 +21,9 @@ #ifndef _CROSSFIRE_H_ #define _CROSSFIRE_H_ +#include +#include "dataconstants.h" + // Device address #define BROADCAST_ADDRESS 0x00 #define RADIO_ADDRESS 0xEA @@ -86,10 +89,10 @@ const uint8_t CROSSFIRE_PERIODS[] = { 4, 16, }; -#define CROSSFIRE_BAUDRATE CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate] +#define CROSSFIRE_BAUDRATE CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate] #define CROSSFIRE_PERIOD CROSSFIRE_PERIODS[g_eeGeneral.telemetryBaudrate] #else -#define CROSSFIRE_BAUDRATE 400000 +#define CROSSFIRE_BAUDRATE 400000 #define CROSSFIRE_PERIOD 4 // 4ms #endif diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 02622bfeb..8098a8a74 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -20,10 +20,78 @@ #include "opentx.h" -void processFrskyTelemetryData(uint8_t data) +bool checkPXX2PacketCRC(const uint8_t * packet) +{ + // TODO ... + + return true; + // TRACE("checkPXX2PacketCRC(): checksum error "); + // DUMP(packet, FRSKY_SPORT_PACKET_SIZE); +} + +void createFrSkyPXX2Sensor(uint16_t type, uint8_t value){ + uint8_t buffer[5] = {0x18, 0x10, 0, 0, 0}; + buffer[2] = type & 0xF; + buffer[3] = type >> 8; + buffer[4] = value; + sportProcessTelemetryPacketWithoutCrc(buffer); +} + +void processFrskyPXX2Data(uint8_t data) { static uint8_t dataState = STATE_DATA_IDLE; + switch (dataState) { + case STATE_DATA_IDLE: + if (data == START_STOP) { + telemetryRxBufferCount = 0; + dataState = STATE_DATA_START; + } + break; + + case STATE_DATA_START: + if (telemetryRxBufferCount == 0 && data > 0x0C) { + // wrong length + telemetryRxBufferCount = 0; + dataState = STATE_DATA_IDLE; + } + else if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + telemetryRxBuffer[telemetryRxBufferCount++] = data; + if (telemetryRxBuffer[0] + 3 /* 1 byte for length, 2 bytes for CRC */ == telemetryRxBufferCount) { + if (checkPXX2PacketCRC(telemetryRxBuffer)) { + R9ModuleStreaming = TELEMETRY_TIMEOUT10ms; // reset counter only if valid packets are being detected + uint8_t R9Region = (telemetryRxBuffer[3] & 0x30) >> 4; + if (R9Region != 0x04) { + g_model.moduleData[EXTERNAL_MODULE].r9m.region = R9Region; + } + if (telemetryRxBuffer[2] & 0x80) { + createFrSkyPXX2Sensor(RSSI_ID, telemetryRxBuffer[2] & 0x7f); + } + else { + createFrSkyPXX2Sensor(BATT_ID, telemetryRxBuffer[2] & 0x7f); + } + if((telemetryRxBuffer[3] & 0x04) == 0) { + createFrSkyPXX2Sensor(R9_PWR_ID, (telemetryRxBuffer[3] & 0x03)); + } + if (telemetryRxBuffer[0] == 0x0C) { + sportProcessTelemetryPacketWithoutCrc(telemetryRxBuffer + 5 /* LEN, TYPE, RSSI/BAT, TP/SS/FW_T, FW_VER, Data ID */); + } + } + telemetryRxBufferCount = 0; + dataState = STATE_DATA_IDLE; + } + } + else { + // overflow guard + telemetryRxBufferCount = 0; + dataState = STATE_DATA_IDLE; + } + break; + } +} + +void processFrskyTelemetryData(uint8_t data) +{ #if defined(PCBSKY9X) && defined(BLUETOOTH) // TODO if (g_model.bt_telemetry) btPushByte(data); @@ -41,6 +109,19 @@ void processFrskyTelemetryData(uint8_t data) } #endif + if (pushFrskyTelemetryData(data)) { + if (IS_FRSKY_SPORT_PROTOCOL()) { + sportProcessTelemetryPacket(telemetryRxBuffer); + } else { + frskyDProcessPacket(telemetryRxBuffer); + } + } +} + +bool pushFrskyTelemetryData(uint8_t data) +{ + static uint8_t dataState = STATE_DATA_IDLE; + switch (dataState) { case STATE_DATA_START: if (data == START_STOP) { @@ -68,8 +149,8 @@ void processFrskyTelemetryData(uint8_t data) } else { // end of frame detected - frskyDProcessPacket(telemetryRxBuffer); dataState = STATE_DATA_IDLE; + return true; } break; } @@ -96,9 +177,13 @@ void processFrskyTelemetryData(uint8_t data) #if defined(TELEMETRY_FRSKY_SPORT) if (IS_FRSKY_SPORT_PROTOCOL() && telemetryRxBufferCount >= FRSKY_SPORT_PACKET_SIZE) { - sportProcessPacket(telemetryRxBuffer); + // end of frame detected dataState = STATE_DATA_IDLE; + return true; } #endif + + return false; } + diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index 96145e3e7..b665f4fdf 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -23,6 +23,7 @@ #include "../definitions.h" #include "telemetry_holders.h" +#include "../io/frsky_pxx2.h" // Receive buffer state machine state enum enum FrSkyDataState { @@ -32,12 +33,7 @@ enum FrSkyDataState { STATE_DATA_XOR, }; -#if defined(PXX2) -#include "io/pxx2.h" -#define FRSKY_SPORT_BAUDRATE PXX2_BAUDRATE -#else #define FRSKY_SPORT_BAUDRATE 57600 -#endif #define FRSKY_D_BAUDRATE 9600 @@ -196,9 +192,12 @@ enum FrSkyDataState { #define BATT_ID 0xf104 #define RAS_ID 0xf105 #define XJT_VERSION_ID 0xf106 +#define R9_PWR_ID 0xf107 #define FUEL_QTY_FIRST_ID 0x0a10 #define FUEL_QTY_LAST_ID 0x0a1f + + // Default sensor data IDs (Physical IDs + CRC) #define DATA_ID_VARIO 0x00 // 0 #define DATA_ID_FLVSS 0xA1 // 1 @@ -208,7 +207,6 @@ enum FrSkyDataState { #define DATA_ID_SP2UH 0x45 // 5 #define DATA_ID_SP2UR 0xC6 // 6 - #if defined(NO_RAS) #define IS_RAS_VALUE_VALID() (false) #elif defined(PCBX10) @@ -221,13 +219,6 @@ enum FrSkyDataState { #define IS_HIDDEN_TELEMETRY_VALUE(id) ((id == SP2UART_A_ID) || (id == SP2UART_B_ID) || (id == XJT_VERSION_ID) || (id == RAS_ID) || (id == FACT_TEST_ID)) -enum AlarmLevel { - alarm_off = 0, - alarm_yellow = 1, - alarm_orange = 2, - alarm_red = 3 -}; - #define ALARM_GREATER(channel, alarm) ((g_model.frsky.channels[channel].alarms_greater >> alarm) & 1) #define ALARM_LEVEL(channel, alarm) ((g_model.frsky.channels[channel].alarms_level >> (2*alarm)) & 3) @@ -289,11 +280,11 @@ typedef enum { // FrSky D Telemetry Protocol void processHubPacket(uint8_t id, int16_t value); -void frskyDSendNextAlarm(); void frskyDProcessPacket(const uint8_t *packet); // FrSky S.PORT Telemetry Protocol void sportProcessTelemetryPacket(const uint8_t * packet); +void sportProcessTelemetryPacketWithoutCrc(const uint8_t * packet); void telemetryWakeup(); void telemetryReset(); @@ -313,14 +304,6 @@ enum TelemetryProtocol TELEM_PROTO_FLYSKY_IBUS, }; -enum TelemAnas { - TELEM_ANA_A1, - TELEM_ANA_A2, - TELEM_ANA_A3, - TELEM_ANA_A4, - TELEM_ANA_COUNT -}; - struct TelemetryData { TelemetryValueWithMin swr; // TODO Min not needed TelemetryValueWithMin rssi; // TODO Min not needed @@ -330,12 +313,8 @@ struct TelemetryData { extern TelemetryData telemetryData; - typedef uint16_t frskyCellVoltage_t; - -void frskySetCellsCount(uint8_t cellscount); -void frskySetCellVoltage(uint8_t battnumber, frskyCellVoltage_t cellVolts); -void frskyUpdateCells(); - +bool pushFrskyTelemetryData(uint8_t data); // returns true when end of frame detected void processFrskyTelemetryData(uint8_t data); +void processFrskyPXX2Data(uint8_t data); #endif // _FRSKY_H_ diff --git a/radio/src/telemetry/frsky_d_arm.cpp b/radio/src/telemetry/frsky_d.cpp similarity index 100% rename from radio/src/telemetry/frsky_d_arm.cpp rename to radio/src/telemetry/frsky_d.cpp diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp new file mode 100644 index 000000000..b7e54d887 --- /dev/null +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -0,0 +1,275 @@ +/* + * 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. + */ + +#include +#include "opentx.h" + +class Pxx2Telemetry +{ + protected: + static void processGetHardwareInfoFrame(uint8_t module, uint8_t *frame); + + static void processReceiverSettingsFrame(uint8_t module, uint8_t *frame); + + static void processRegisterFrame(uint8_t module, uint8_t * frame); + + static void processBindFrame(uint8_t module, uint8_t * frame); + + static void processTelemetryFrame(uint8_t module, uint8_t * frame); + + static void processSpectrumFrame(uint8_t module, uint8_t * frame); + + static void processRadioFrame(uint8_t module, uint8_t * frame); + + static void processPowerMeterFrame(uint8_t module, uint8_t * frame); + + public: +}; + +void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_GET_HARDWARE_INFO) { + return; + } + + uint8_t index = frame[3]; + if (index == 0xFF) + memcpy(&reusableBuffer.hardwareAndSettings.modules[module].information, &frame[4], sizeof(PXX2HardwareInformation)); + else if (index < PXX2_MAX_RECEIVERS_PER_MODULE) + memcpy(&reusableBuffer.hardwareAndSettings.modules[module].receivers[index].information, &frame[4], sizeof(PXX2HardwareInformation)); +} + +void processModuleSettingsFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_MODULE_SETTINGS) { + return; + } + + // Flag1 + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = frame[4] >> 4; + if (frame[4] & PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA) + reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = 1; + + // Power + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = frame[5]; + + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.hardwareAndSettings.moduleSettings.timeout = 0; + moduleSettings[module].mode = MODULE_MODE_NORMAL; +} + +void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_RECEIVER_SETTINGS) { + return; + } + + if (frame[4] & PXX2_RX_SETTINGS_FLAG1_FASTPWM) + reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate = 1; + + if (frame[4] & PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED) + reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled = 1; + + uint8_t outputsCount = min(16, frame[0] - 4); + reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount = outputsCount; + for (uint8_t pin = 0; pin < outputsCount; pin++) { + reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin] = frame[5 + pin]; + } + + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleSettings[module].mode = MODULE_MODE_NORMAL; +} + +void processRegisterFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_REGISTER) { + return; + } + + switch(frame[3]) { + case 0x00: + if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_START) { + // RX_NAME follows, we store it for the next step + str2zchar(reusableBuffer.moduleSetup.pxx2.registerRxName, (const char *)&frame[4], PXX2_LEN_RX_NAME); + reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_RECEIVED; + } + break; + + case 0x01: + if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_RX_NAME_SELECTED) { + // RX_NAME + PASSWORD follow, we check they are good + if (cmpStrWithZchar((char *)&frame[4], reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME) && + cmpStrWithZchar((char *)&frame[12], g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID)) { + reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_OK; + moduleSettings[module].mode = MODULE_MODE_NORMAL; + POPUP_INFORMATION(STR_REG_OK); + } else { + TRACE("KO %s %s", &frame[4], reusableBuffer.moduleSetup.pxx2.registerRxName); + } + } + break; + } +} + +void processBindFrame(uint8_t module, uint8_t * frame) +{ + if (moduleSettings[module].mode != MODULE_MODE_BIND) { + return; + } + + switch(frame[3]) { + case 0x00: + if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_START) { + bool found = false; + for (uint8_t i=0; i reusableBuffer.powerMeter.peak) { + reusableBuffer.powerMeter.peak = reusableBuffer.powerMeter.power; + } +} + +void processModuleFrame(uint8_t module, uint8_t *frame) +{ + switch (frame[2]) { + case PXX2_TYPE_ID_HW_INFO: + processGetHardwareInfoFrame(module, frame); + break; + + case PXX2_TYPE_ID_TX_SETTINGS: + processModuleSettingsFrame(module, frame); + break; + + case PXX2_TYPE_ID_RX_SETTINGS: + processReceiverSettingsFrame(module, frame); + break; + + case PXX2_TYPE_ID_REGISTER: + processRegisterFrame(module, frame); + break; + + case PXX2_TYPE_ID_BIND: + processBindFrame(module, frame); + break; + + case PXX2_TYPE_ID_TELEMETRY: + processTelemetryFrame(module, frame); + break; + } +} + +void processToolsFrame(uint8_t module, uint8_t * frame) +{ + switch (frame[2]) { + case PXX2_TYPE_ID_POWER_METER: + processPowerMeterFrame(module, frame); + break; + + case PXX2_TYPE_ID_SPECTRUM: + processSpectrumAnalyserFrame(module, frame); + break; + } +} + +void processPXX2Frame(uint8_t module, uint8_t *frame) +{ + switch (frame[1]) { + case PXX2_TYPE_C_MODULE: + processModuleFrame(module, frame); + break; + + case PXX2_TYPE_C_POWER_METER: + processToolsFrame(module, frame); + break; + + default: + break; + } +} + +void pushPXX2TelemetryPacket(uint8_t module, uint8_t rx_uid, SportTelemetryPacket * packet) +{ + // Flag0 + outputTelemetryBuffer.push(rx_uid); + + for (uint8_t i=1; iraw[i]; + outputTelemetryBuffer.push(byte); + } + + outputTelemetryBuffer.setDestination(module); +} diff --git a/radio/src/telemetry/frsky_sport.cpp b/radio/src/telemetry/frsky_sport.cpp index 0309ecb2f..3bc4edde9 100644 --- a/radio/src/telemetry/frsky_sport.cpp +++ b/radio/src/telemetry/frsky_sport.cpp @@ -36,6 +36,7 @@ const FrSkySportSensor sportSensors[] = { { A3_FIRST_ID, A3_LAST_ID, 0, ZSTR_A3, UNIT_VOLTS, 2 }, { A4_FIRST_ID, A4_LAST_ID, 0, ZSTR_A4, UNIT_VOLTS, 2 }, { BATT_ID, BATT_ID, 0, ZSTR_BATT, UNIT_VOLTS, 1 }, + { R9_PWR_ID, R9_PWR_ID, 0, ZSTR_R9PW, UNIT_MILLIWATTS, 0 }, { T1_FIRST_ID, T1_LAST_ID, 0, ZSTR_TEMP1, UNIT_CELSIUS, 0 }, { T2_FIRST_ID, T2_LAST_ID, 0, ZSTR_TEMP2, UNIT_CELSIUS, 0 }, { RPM_FIRST_ID, RPM_LAST_ID, 0, ZSTR_RPM, UNIT_RPMS, 0 }, @@ -94,7 +95,7 @@ const FrSkySportSensor * getFrSkySportSensor(uint16_t id, uint8_t subId=0) return result; } -bool checkSportPacket(const uint8_t *packet) +bool checkSportPacket(const uint8_t * packet) { short crc = 0; for (int i=1; i= 5) processMultiStatusPacket(data); break; + case DSMBindPacket: if (len >= 10) processDSMBindPacket(data); break; + case SpektrumTelemetry: // processSpektrumPacket expects data[0] to be the telemetry indicator 0xAA but does not check it, // just send one byte of our header instead @@ -121,41 +123,50 @@ static void processMultiTelemetryPaket(const uint8_t *packet) else TRACE("[MP] Received spektrum telemetry len %d < 17", len); break; + case FlyskyIBusTelemetry: if (len >= 28) processFlySkyPacket(data); else TRACE("[MP] Received IBUS telemetry len %d < 28", len); break; + case FrSkyHubTelemetry: if (len >= 4) frskyDProcessPacket(data); else TRACE("[MP] Received Frsky HUB telemetry len %d < 4", len); break; + +#if defined(MULTI_SPORT) case FrSkySportTelemtry: if (len >= 4) sportProcessTelemetryPacket(data); else TRACE("[MP] Received sport telemetry len %d < 4", len); break; +#endif + case InputSync: if (len >= 6) processMultiSyncPacket(data); else TRACE("[MP] Received input sync len %d < 6", len); break; + case ConfigCommand: // Just an ack to our command, ignore for now break; + case FrskySportPolling: #if defined(LUA) - if (len >= 1 && outputTelemetryBufferSize > 0 && data[0] == outputTelemetryBufferTrigger) { + if (len >= 1 && outputTelemetryBuffer.size > 0 && data[0] == outputTelemetryBuffer.trigger) { TRACE("MP Sending sport data out."); - sportSendBuffer(outputTelemetryBuffer, outputTelemetryBufferSize); + sportSendBuffer(outputTelemetryBuffer.data, outputTelemetryBuffer.size); } #endif break; + default: TRACE("[MP] Unkown multi packet type 0x%02X, len %d", type, len); break; diff --git a/radio/src/telemetry/spektrum.cpp b/radio/src/telemetry/spektrum.cpp index dd3d9246f..96c7102d0 100644 --- a/radio/src/telemetry/spektrum.cpp +++ b/radio/src/telemetry/spektrum.cpp @@ -173,14 +173,14 @@ const SpektrumSensor spektrumSensors[] = { {I2C_CELLS, 8, uint16, ZSTR_CELLS, UNIT_VOLTS, 2}, {I2C_CELLS, 10, uint16, ZSTR_CELLS, UNIT_VOLTS, 2}, {I2C_CELLS, 12, uint16, ZSTR_TEMP2, UNIT_CELSIUS, 2}, - + // Vario-S {0x40, 0, int16, ZSTR_ALT, UNIT_METERS, 1}, {0x40, 2, int16, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 1}, // 0x50-0x56 custom 3rd party sensors //{0x50, 0, int16, ZSTR_} - + // 0x7d are transmitter channels frame data [7], probably only available on the Spektrum // telemetry bus on the model itself @@ -333,7 +333,7 @@ void processSpektrumPacket(const uint8_t *packet) } telemetryStreaming = TELEMETRY_TIMEOUT10ms; } - + uint16_t pseudoId = (sensor->i2caddress << 8 | sensor->startByte); setTelemetryValue(TELEM_PROTO_SPEKTRUM, pseudoId, 0, instance, value, sensor->unit, sensor->precision); } @@ -400,8 +400,7 @@ void processDSMBindPacket(const uint8_t *packet) setTelemetryValue(TELEM_PROTO_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) == MM_RF_PROTO_DSM2 - && moduleFlag[EXTERNAL_MODULE] == MODULE_BIND) { + if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2 && moduleSettings[EXTERNAL_MODULE].mode == MODULE_MODE_BIND) { multiBindStatus=MULTI_BIND_FINISHED; } } diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 95af31711..04b37cf0b 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -18,9 +18,10 @@ * GNU General Public License for more details. */ -#include "opentx.h" +#include uint8_t telemetryStreaming = 0; +uint8_t R9ModuleStreaming = 0; uint8_t telemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; // Receive buffer. 9 bytes (full packet), worst case 18 bytes with byte-stuffing (+1) uint8_t telemetryRxBufferCount = 0; @@ -38,44 +39,69 @@ uint8_t telemetryProtocol = 255; uint8_t serialInversion = 0; #endif - void processTelemetryData(uint8_t data) { #if defined(CROSSFIRE) - if (telemetryProtocol == PROTOCOL_PULSES_CROSSFIRE) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_CROSSFIRE) { processCrossfireTelemetryData(data); return; } #endif + #if defined(MULTIMODULE) - if (telemetryProtocol == PROTOCOL_SPEKTRUM) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_SPEKTRUM) { processSpektrumTelemetryData(data); return; } - if (telemetryProtocol == PROTOCOL_FLYSKY_IBUS) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_FLYSKY_IBUS) { processFlySkyTelemetryData(data); return; } - if (telemetryProtocol == PROTOCOL_MULTIMODULE) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE) { processMultiTelemetryData(data); return; } #endif + + if (telemetryProtocol == PROTOCOL_TELEMETRY_PXX2) { + processFrskyPXX2Data(data); + return; + } + processFrskyTelemetryData(data); } void telemetryWakeup() { uint8_t requiredTelemetryProtocol = modelTelemetryProtocol(); + #if defined(REVX) uint8_t requiredSerialInversion = g_model.moduleData[EXTERNAL_MODULE].invertedSerial; if (telemetryProtocol != requiredTelemetryProtocol || serialInversion != requiredSerialInversion) { serialInversion = requiredSerialInversion; -#else - if (telemetryProtocol != requiredTelemetryProtocol) { -#endif telemetryInit(requiredTelemetryProtocol); } +#else + if (telemetryProtocol != requiredTelemetryProtocol) { + telemetryInit(requiredTelemetryProtocol); + } +#endif + +#if defined(INTMODULE_USART) || defined(EXTMODULE_USART) + uint8_t frame[PXX2_FRAME_MAXLENGTH]; + + #if defined(INTMODULE_USART) + while (intmoduleFifo.getFrame(frame)) { + processPXX2Frame(INTERNAL_MODULE, frame); + } + #endif + + #if defined(EXTMODULE_USART) + while (extmoduleFifo.getFrame(frame)) { + processPXX2Frame(EXTERNAL_MODULE, frame); + } + #endif +#endif #if defined(STM32) uint8_t data; @@ -87,7 +113,7 @@ void telemetryWakeup() } while (telemetryGetByte(&data)); } #elif defined(PCBSKY9X) - if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { uint8_t data; while (telemetrySecondPortReceive(data)) { processTelemetryData(data); @@ -99,7 +125,6 @@ void telemetryWakeup() } #endif - for (int i=0; i 0x33) static tmr10ms_t alarmsCheckTime = 0; @@ -194,7 +219,9 @@ void telemetryInterrupt10ms() wshhStreaming--; } #endif - + if (R9ModuleStreaming > 0) { + R9ModuleStreaming--; + } if (telemetryStreaming > 0) { telemetryStreaming--; } @@ -223,27 +250,27 @@ void telemetryInit(uint8_t protocol) { telemetryProtocol = protocol; - if (protocol == PROTOCOL_FRSKY_D) { + if (protocol == PROTOCOL_TELEMETRY_FRSKY_D) { telemetryPortInit(FRSKY_D_BAUDRATE, TELEMETRY_SERIAL_DEFAULT); } #if defined(MULTIMODULE) - else if (protocol == PROTOCOL_MULTIMODULE || protocol == PROTOCOL_FLYSKY_IBUS) { + else if (protocol == PROTOCOL_TELEMETRY_MULTIMODULE || protocol == PROTOCOL_TELEMETRY_FLYSKY_IBUS) { // The DIY Multi module always speaks 100000 baud regardless of the telemetry protocol in use telemetryPortInit(MULTIMODULE_BAUDRATE, TELEMETRY_SERIAL_8E2); #if defined(LUA) - outputTelemetryBufferSize = 0; - outputTelemetryBufferTrigger = 0x7E; + outputTelemetryBuffer.size = 0; + outputTelemetryBuffer.trigger = 0x7E; #endif } - else if (protocol == PROTOCOL_SPEKTRUM) { + else if (protocol == PROTOCOL_TELEMETRY_SPEKTRUM) { // Spektrum's own small race RX (SPM4648) uses 125000 8N1, use the same since there is no real standard telemetryPortInit(125000, TELEMETRY_SERIAL_DEFAULT); } #endif #if defined(CROSSFIRE) - else if (protocol == PROTOCOL_PULSES_CROSSFIRE) { + else if (protocol == PROTOCOL_TELEMETRY_CROSSFIRE) { telemetryPortInit(CROSSFIRE_BAUDRATE, TELEMETRY_SERIAL_DEFAULT); #if defined(LUA) outputTelemetryBufferSize = 0; @@ -254,17 +281,22 @@ void telemetryInit(uint8_t protocol) #endif #if defined(SERIAL2) || defined(PCBSKY9X) - else if (protocol == PROTOCOL_FRSKY_D_SECONDARY) { + else if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { telemetryPortInit(0, TELEMETRY_SERIAL_DEFAULT); - serial2TelemetryInit(PROTOCOL_FRSKY_D_SECONDARY); + serial2TelemetryInit(PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY); } #endif + else if (protocol == PROTOCOL_TELEMETRY_PXX2) { + telemetryPortInit(PXX2_ON_SPORT_BAUDRATE, TELEMETRY_SERIAL_WITHOUT_DMA); +#if defined(LUA) + outputTelemetryBuffer.reset(); +#endif + } else { telemetryPortInit(FRSKY_SPORT_BAUDRATE, TELEMETRY_SERIAL_WITHOUT_DMA); #if defined(LUA) - outputTelemetryBufferSize = 0; - outputTelemetryBufferTrigger = 0x7E; + outputTelemetryBuffer.reset(); #endif } @@ -299,9 +331,7 @@ void logTelemetryWriteByte(uint8_t data) } #endif -uint8_t outputTelemetryBuffer[TELEMETRY_OUTPUT_FIFO_SIZE] __DMA; -uint8_t outputTelemetryBufferSize = 0; -uint8_t outputTelemetryBufferTrigger = 0; +OutputTelemetryBuffer outputTelemetryBuffer __DMA; #if defined(LUA) Fifo * luaInputTelemetryFifo = NULL; diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index a35d6b3b0..bdab8d178 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -26,9 +26,7 @@ #include "frsky.h" #endif -#if defined(CROSSFIRE) - #include "crossfire.h" -#endif +#include "crossfire.h" #if defined(MULTIMODULE) #include "spektrum.h" #include "flysky_ibus.h" @@ -36,6 +34,7 @@ #endif extern uint8_t telemetryStreaming; // >0 (true) == data is streaming in. 0 = no data detected for some time +extern uint8_t R9ModuleStreaming; // >0 (true) == R9 module is connected and sending data 0 = no data detected for some time #if defined(WS_HOW_HIGH) extern uint8_t wshhStreaming; @@ -97,7 +96,6 @@ void delTelemetryIndex(uint8_t index); int availableTelemetryIndex(); int lastUsedTelemetryIndex(); -int32_t getTelemetryValue(uint8_t index, uint8_t & prec); int32_t convertTelemetryValue(int32_t value, uint8_t unit, uint8_t prec, uint8_t destUnit, uint8_t destPrec); void frskySportSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); @@ -107,38 +105,45 @@ void frskyDSetDefault(int index, uint16_t id); #define IS_SPEED_UNIT(unit) ((unit) >= UNIT_KTS && (unit) <= UNIT_MPH) extern uint8_t telemetryProtocol; -#define IS_FRSKY_D_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_D) + #if defined (MULTIMODULE) #define IS_D16_MULTI() ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FRSKY) && (g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH)) -#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_MULTIMODULE && IS_D16_MULTI())) +#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && IS_D16_MULTI())) #else -#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_SPORT) +#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT) #endif -#define IS_SPEKTRUM_PROTOCOL() (telemetryProtocol == PROTOCOL_SPEKTRUM) +#define IS_SPEKTRUM_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_SPEKTRUM) inline uint8_t modelTelemetryProtocol() { #if defined(CROSSFIRE) if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_CROSSFIRE) { - return PROTOCOL_PULSES_CROSSFIRE; + return PROTOCOL_TELEMETRY_CROSSFIRE; } #endif - + if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) { return g_model.telemetryProtocol; } - + + if (!IS_INTERNAL_MODULE_ENABLED() && isModulePXX2(EXTERNAL_MODULE)) { + return PROTOCOL_TELEMETRY_PXX2; + } + + if (!IS_INTERNAL_MODULE_ENABLED() && isModulePXX(EXTERNAL_MODULE)) { + return PROTOCOL_TELEMETRY_FRSKY_SPORT; + } #if defined(MULTIMODULE) if (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { - return PROTOCOL_MULTIMODULE; + return PROTOCOL_TELEMETRY_MULTIMODULE; } #endif // default choice - return PROTOCOL_FRSKY_SPORT; + return PROTOCOL_TELEMETRY_FRSKY_SPORT; } - #include "telemetry_sensors.h" +#include "telemetry_sensors.h" #if defined(LOG_TELEMETRY) && !defined(SIMU) void logTelemetryWriteStart(); @@ -150,20 +155,40 @@ void logTelemetryWriteByte(uint8_t data); #define LOG_TELEMETRY_WRITE_BYTE(data) #endif -#define TELEMETRY_OUTPUT_FIFO_SIZE 16 -extern uint8_t outputTelemetryBuffer[TELEMETRY_OUTPUT_FIFO_SIZE] __DMA; -extern uint8_t outputTelemetryBufferSize; -extern uint8_t outputTelemetryBufferTrigger; +#define TELEMETRY_OUTPUT_FIFO_SIZE 20 -inline void telemetryOutputPushByte(uint8_t byte) -{ - outputTelemetryBuffer[outputTelemetryBufferSize++] = byte; -} +class OutputTelemetryBuffer { + public: + OutputTelemetryBuffer() { + reset(); + } -inline void telemetryOutputSetTrigger(uint8_t byte) -{ - outputTelemetryBufferTrigger = byte; -} + void push(uint8_t byte) { + data[size++] = byte; + } + + void setTrigger(uint8_t byte) { + trigger = byte; + } + + void setDestination(uint8_t module) { + destination = module; + } + + void reset() { + size = 0; + trigger = 0x7E; + destination = 0xFF; + } + + public: + uint8_t data[TELEMETRY_OUTPUT_FIFO_SIZE]; + uint8_t size; + uint8_t trigger; + uint8_t destination; +}; + +extern OutputTelemetryBuffer outputTelemetryBuffer __DMA; #if defined(LUA) #define LUA_TELEMETRY_INPUT_FIFO_SIZE 256 @@ -176,5 +201,7 @@ extern Fifo * luaInputTelemetryFifo; #define IS_TELEMETRY_INTERNAL_MODULE() (false) #endif -#endif // _TELEMETRY_H_ +void processPXX2Frame(uint8_t module, uint8_t *frame); +void pushPXX2TelemetryPacket(uint8_t module, uint8_t rx_uid, SportTelemetryPacket * packet); +#endif // _TELEMETRY_H_ diff --git a/radio/src/telemetry/telemetry_sensors.cpp b/radio/src/telemetry/telemetry_sensors.cpp index 049f3742a..d7ff7e15e 100644 --- a/radio/src/telemetry/telemetry_sensors.cpp +++ b/radio/src/telemetry/telemetry_sensors.cpp @@ -33,7 +33,7 @@ bool isFaiForbidden(source_t idx) switch (telemetryProtocol) { - case PROTOCOL_FRSKY_SPORT: + case PROTOCOL_TELEMETRY_FRSKY_SPORT: if (sensor->id == RSSI_ID) { return false; } @@ -42,7 +42,7 @@ bool isFaiForbidden(source_t idx) } break; - case PROTOCOL_FRSKY_D: + case PROTOCOL_TELEMETRY_FRSKY_D: if (sensor->id == D_RSSI_ID) { return false; } @@ -52,7 +52,7 @@ bool isFaiForbidden(source_t idx) break; #if defined(CROSSFIRE) - case PROTOCOL_PULSES_CROSSFIRE: + case PROTOCOL_TELEMETRY_CROSSFIRE: if (sensor->id == RX_RSSI1_INDEX) { return false; } diff --git a/radio/src/thirdparty/CoOS/OsConfig.h b/radio/src/thirdparty/CoOS/OsConfig.h index c56e47529..341f262d0 100644 --- a/radio/src/thirdparty/CoOS/OsConfig.h +++ b/radio/src/thirdparty/CoOS/OsConfig.h @@ -85,7 +85,11 @@ System frequency (Hz). /*!< systick frequency (Hz). */ +#if defined(STM32) +#define CFG_SYSTICK_FREQ (1000) +#else #define CFG_SYSTICK_FREQ (500) +#endif /*!< max systerm api call num in ISR. diff --git a/radio/src/trainer_input.cpp b/radio/src/trainer_input.cpp index 838c78297..a84ed0d6e 100644 --- a/radio/src/trainer_input.cpp +++ b/radio/src/trainer_input.cpp @@ -24,7 +24,7 @@ int16_t ppmInput[MAX_TRAINER_CHANNELS]; uint8_t ppmInputValidityTimer; -#include "audio_arm.h" +#include "audio.h" void checkTrainerSignalWarning() { diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index c804a3fb3..7dc5add48 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -88,10 +88,12 @@ const char STR_OPEN9X[] = ISTR(VVARIOCENTER) ISTR(COUNTRYCODES) ISTR(USBMODES) + ISTR(JACKMODES) ISTR(VFAILSAFE) ISTR(VTRAINERMODES) ISTR(TARANIS_PROTOCOLS) ISTR(R9M_REGION) + ISTR(R9MFLEX_FREQ) ISTR(R9M_FCC_POWER_VALUES) ISTR(R9M_LBT_POWER_VALUES) ISTR(TELEMETRY_PROTOCOLS) @@ -113,7 +115,8 @@ const char STR_OPEN9X[] = ; // The 0-terminated-strings -const char STR_POPUPS[] = TR_POPUPS; +const char STR_POPUPS_ENTER_EXIT[] = TR_POPUPS_ENTER_EXIT; +const char STR_OK[] = TR_OK; #if !defined(OFS_EXIT) const char STR_EXIT[] = TR_EXIT; #endif @@ -144,6 +147,7 @@ const char STR_PPMFRAME[] = TR_PPMFRAME; const char STR_REFRESHRATE[] = TR_REFRESHRATE; const char SSTR_WARN_BATTVOLTAGE[] = STR_WARN_BATTVOLTAGE; const char STR_MS[] = TR_MS; +const char STR_FREQUENCY[] = TR_FREQUENCY; const char STR_SWITCH[] = TR_SWITCH; const char STR_TRIMS[] = TR_TRIMS; const char STR_FADEIN[] = TR_FADEIN; @@ -350,6 +354,8 @@ const char STR_MENUGLOBALVARS[] = TR_MENUGLOBALVARS; const char STR_RECEIVER_NUM[] = TR_RECEIVER_NUM; const char STR_RECEIVER[] = TR_RECEIVER; const char STR_REBIND[] = TR_REBIND; +const char STR_REG_OK[] = TR_REG_OK; +const char STR_BIND_OK[] = TR_BIND_OK; #endif const char STR_SYNCMENU[] = TR_SYNCMENU; @@ -359,8 +365,12 @@ const char STR_MODULE_TELEMETRY[] = TR_MODULE_TELEMETRY; const char STR_MODULE_TELEM_ON[] = TR_MODULE_TELEM_ON; const char STR_COUNTRYCODE[] = TR_COUNTRYCODE; const char STR_USBMODE[] = TR_USBMODE; +const char STR_JACKMODE[] = TR_JACKMODE; const char STR_FAILSAFE[] = TR_FAILSAFE; const char STR_FAILSAFESET[] = TR_FAILSAFESET; +const char STR_REG_ID[] = TR_REG_ID; +const char STR_OWNER_ID[] = TR_OWNER_ID; +const char STR_PINMAPSET[] = TR_PINMAPSET; const char STR_HOLD[] = TR_HOLD; const char STR_NONE[] = TR_NONE; const char STR_MENUSENSOR[] = TR_MENUSENSOR; @@ -397,7 +407,6 @@ const char STR_WAV_VOLUME[] = INDENT TR_WAV_VOLUME; const char STR_BG_VOLUME[] = INDENT TR_BG_VOLUME; const char STR_PERSISTENT_MAH[] = TR_PERSISTENT_MAH; -#if defined(NAVIGATION_MENUS) const char STR_SELECT_MODEL[] = TR_SELECT_MODEL; const char STR_CREATE_CATEGORY[] = TR_CREATE_CATEGORY; const char STR_RENAME_CATEGORY[] = TR_RENAME_CATEGORY; @@ -427,7 +436,6 @@ const char STR_USB_MASS_STORAGE[] = TR_USB_MASS_STORAGE; const char STR_USB_SERIAL[] = TR_USB_SERIAL; const char STR_SETUP_SCREENS[] = TR_SETUP_SCREENS; const char STR_MONITOR_SCREENS[] = TR_MONITOR_SCREENS; -#endif #if defined(MULTIMODULE) const char STR_MULTI_CUSTOM[] = TR_MULTI_CUSTOM; @@ -454,7 +462,7 @@ const char STR_SUBTYPE[] = TR_SUBTYPE; const char STR_RESET_BTN[] = TR_RESET_BTN; const char STR_DEBUG[] = TR_DEBUG; -const char STR_SWITCHES_BTN[] = TR_SWITCHES_BTN; +const char STR_KEYS_BTN[] = TR_KEYS_BTN; const char STR_ANALOGS_BTN[] = TR_ANALOGS_BTN; const char STR_CALIB_BTN[] = TR_CALIB_BTN; @@ -485,7 +493,6 @@ const char STR_NIGHTLY_NOTSAFE[] = TR_NIGHTLY_NOTSAFE; const char STR_WRONG_SDCARDVERSION[] = TR_WRONG_SDCARDVERSION; const char STR_WRONG_PCBREV[] = TR_WRONG_PCBREV; const char STR_EMERGENCY_MODE[] = TR_EMERGENCY_MODE; -const char STR_PCBREV_ERROR[] = TR_PCBREV_ERROR; const char STR_NO_FAILSAFE[] = TR_NO_FAILSAFE; const char STR_KEYSTUCK[] = TR_KEYSTUCK; @@ -553,11 +560,9 @@ const char STR_FLASH_BOOTLOADER[] = TR_FLASH_BOOTLOADER; const char STR_FLASH_INTERNAL_MODULE[] = TR_FLASH_INTERNAL_MODULE; const char STR_FLASH_EXTERNAL_MODULE[] = TR_FLASH_EXTERNAL_MODULE; const char STR_FIRMWARE_UPDATE_ERROR[] = TR_FIRMWARE_UPDATE_ERROR; +const char STR_FIRMWARE_UPDATE_SUCCESS[] = TR_FIRMWARE_UPDATE_SUCCESS; const char STR_FLASH_EXTERNAL_DEVICE[] = TR_FLASH_EXTERNAL_DEVICE; -const char STR_WRITING[] = TR_WRITING; const char STR_CONFIRM_FORMAT[] = TR_CONFIRM_FORMAT; -const char STR_EEBACKUP[] = TR_EEBACKUP; -const char STR_FACTORYRESET[] = TR_FACTORYRESET; const char STR_CONFIRMRESET[] = TR_CONFIRMRESET; const char STR_TOO_MANY_LUA_SCRIPTS[] = TR_TO_MANY_LUA_SCRIPTS; const char STR_BLCOLOR[] = TR_BLCOLOR; @@ -578,6 +583,9 @@ const char STR_BLCOLOR[] = TR_BLCOLOR; const char STR_TRAINER[] = TR_TRAINER; const char STR_MODULE_BIND[] = TR_MODULE_BIND; +const char STR_TRANSFER_BUTTON[] = TR_TRANSFER_BUTTON; +const char STR_REGISTER_BUTTON[] = TR_REGISTER_BUTTON; +const char STR_RXADD_BUTTON[] = TR_RXADD_BUTTON; const char STR_BINDING_1_8_TELEM_ON[] = TR_BINDING_CH1_8_TELEM_ON; const char STR_BINDING_1_8_TELEM_OFF[] = TR_BINDING_CH1_8_TELEM_OFF; const char STR_BINDING_9_16_TELEM_ON[] = TR_BINDING_CH9_16_TELEM_ON; @@ -636,7 +644,6 @@ const char STR_BLCOLOR[] = TR_BLCOLOR; const char STR_USER_INTERFACE[] = TR_USER_INTERFACE; const char STR_THEME[] = TR_THEME; const char STR_SETUP[] = TR_SETUP; - const char STR_MAINVIEWX[] = TR_MAINVIEWX; const char STR_LAYOUT[] = TR_LAYOUT; const char STR_ADDMAINVIEW[] = TR_ADDMAINVIEW; const char STR_BACKGROUND_COLOR[] = TR_BACKGROUND_COLOR; @@ -647,6 +654,7 @@ const char STR_BLCOLOR[] = TR_BLCOLOR; const char STR_BYTES[] = TR_BYTES; const char STR_ANTENNAPROBLEM[] = TR_ANTENNAPROBLEM; const char STR_MODULE[] = TR_MODULE; +const char STR_RX_NAME[] = TR_RX_NAME; const char STR_ENABLE_POPUP[] = TR_ENABLE_POPUP; const char STR_DISABLE_POPUP[] = TR_DISABLE_POPUP; const char STR_POPUP[] = TR_POPUP; @@ -693,6 +701,7 @@ const char STR_BLCOLOR[] = TR_BLCOLOR; 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_BUTTON_SHARE[] = TR_BUTTON_SHARE; #if MENUS_LOCK == 1 const char STR_UNLOCKED[] = TR_UNLOCKED; @@ -701,6 +710,8 @@ const char STR_BLCOLOR[] = TR_BLCOLOR; #if defined(PCBTARANIS) || defined(DSM2) const char STR_MODULE_RANGE[] = TR_MODULE_RANGE; + const char STR_RECEIVER_OPTIONS[] = TR_RECEIVER_OPTIONS; + const char STR_DEL_BUTTON[] = TR_DEL_BUTTON; #endif #if defined(BLUETOOTH) diff --git a/radio/src/translations.h b/radio/src/translations.h index 3cfadc987..e214f5300 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -185,11 +185,13 @@ extern const char STR_OPEN9X[]; #define OFS_VVARIOCENTER (OFS_VBEEPCOUNTDOWN + sizeof(TR_VBEEPCOUNTDOWN)) #define OFS_COUNTRYCODES (OFS_VVARIOCENTER + sizeof(TR_VVARIOCENTER)) #define OFS_USBMODES (OFS_COUNTRYCODES + sizeof(TR_COUNTRYCODES)) - #define OFS_VFAILSAFE (OFS_USBMODES + sizeof(TR_USBMODES)) + #define OFS_JACKMODES (OFS_USBMODES + sizeof(TR_USBMODES)) + #define OFS_VFAILSAFE (OFS_JACKMODES + sizeof(TR_JACKMODES)) #define OFS_VTRAINERMODES (OFS_VFAILSAFE + sizeof(TR_VFAILSAFE)) #define OFS_TARANIS_PROTOCOLS (OFS_VTRAINERMODES + sizeof(TR_VTRAINERMODES)) - #define OFS_R9M_REGION (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS)) - #define OFS_R9M_FCC_POWER_VALUES (OFS_R9M_REGION + sizeof(TR_R9M_REGION)) + #define OFS_R9M_REGION (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS)) + #define OFS_R9MFLEX_FREQ (OFS_R9M_REGION + sizeof(TR_R9M_REGION)) + #define OFS_R9M_FCC_POWER_VALUES (OFS_R9MFLEX_FREQ + sizeof(TR_R9MFLEX_FREQ)) #define OFS_R9M_LBT_POWER_VALUES (OFS_R9M_FCC_POWER_VALUES + sizeof(TR_R9M_FCC_POWER_VALUES)) #define OFS_TELEMETRY_PROTOCOLS (OFS_R9M_LBT_POWER_VALUES + sizeof(TR_R9M_LBT_POWER_VALUES)) #define OFS_XJT_PROTOCOLS (OFS_TELEMETRY_PROTOCOLS + sizeof(TR_TELEMETRY_PROTOCOLS)) @@ -290,11 +292,13 @@ extern const char STR_OPEN9X[]; #define STR_COUNTRYCODES (STR_OPEN9X + OFS_COUNTRYCODES) #define STR_USBMODES (STR_OPEN9X + OFS_USBMODES) + #define STR_JACKMODES (STR_OPEN9X + OFS_JACKMODES) #define STR_VFAILSAFE (STR_OPEN9X + OFS_VFAILSAFE) #define STR_VTRAINERMODES (STR_OPEN9X + OFS_VTRAINERMODES) #define STR_TARANIS_PROTOCOLS (STR_OPEN9X + OFS_TARANIS_PROTOCOLS) - #define STR_R9M_REGION (STR_OPEN9X + OFS_R9M_REGION) + #define STR_R9M_REGION (STR_OPEN9X + OFS_R9M_REGION) + #define STR_R9MFLEX_FREQ (STR_OPEN9X + OFS_R9MFLEX_FREQ) #define STR_R9M_FCC_POWER_VALUES (STR_OPEN9X + OFS_R9M_FCC_POWER_VALUES) #define STR_R9M_LBT_POWER_VALUES (STR_OPEN9X + OFS_R9M_LBT_POWER_VALUES) #define STR_TELEMETRY_PROTOCOLS (STR_OPEN9X + OFS_TELEMETRY_PROTOCOLS) @@ -324,10 +328,11 @@ extern const char STR_BLUETOOTH_LOCAL_ADDR[]; // The 0-terminated-strings #define NO_INDENT(x) (x)+LEN_INDENT -extern const char STR_POPUPS[]; +extern const char STR_POPUPS_ENTER_EXIT[]; +extern const char STR_OK[]; #if defined(OFS_EXIT) - #define STR_EXIT (STR_POPUPS + OFS_EXIT) + #define STR_EXIT (STR_POPUPS_ENTER_EXIT + OFS_EXIT) #else extern const char STR_EXIT[]; #endif @@ -361,6 +366,7 @@ extern const char STR_PPMFRAME[]; extern const char STR_REFRESHRATE[]; extern const char SSTR_WARN_BATTVOLTAGE[]; extern const char STR_MS[]; +extern const char STR_FREQUENCY[]; extern const char STR_SWITCH[]; extern const char STR_TRIMS[]; extern const char STR_FADEIN[]; @@ -564,6 +570,8 @@ extern const char STR_SUBTYPE[]; extern const char STR_RECEIVER_NUM[]; extern const char STR_RECEIVER[]; extern const char STR_REBIND[]; +extern const char STR_REG_OK[]; +extern const char STR_BIND_OK[]; #endif extern const char STR_SYNCMENU[]; @@ -573,12 +581,17 @@ extern const char STR_MODULE_TELEMETRY[]; extern const char STR_MODULE_TELEM_ON[]; extern const char STR_FAILSAFE[]; extern const char STR_FAILSAFESET[]; +extern const char STR_RECEIVER[]; +extern const char STR_REG_ID[]; +extern const char STR_OWNER_ID[]; +extern const char STR_PINMAPSET[]; extern const char STR_HOLD[]; extern const char STR_NONE[]; extern const char STR_MENUSENSOR[]; extern const char STR_SENSOR[]; extern const char STR_COUNTRYCODE[]; extern const char STR_USBMODE[]; +extern const char STR_JACKMODE[]; extern const char STR_DISABLE_INTERNAL[]; #if defined(TELEMETRY_FRSKY) @@ -616,7 +629,6 @@ extern const char STR_PERSISTENT_MAH[]; #define LEN_CALIB_FIELDS PSIZE(TR_BATT_CALIB) #endif -#if defined(NAVIGATION_MENUS) extern const char STR_SELECT_MODEL[]; extern const char STR_CREATE_CATEGORY[]; extern const char STR_RENAME_CATEGORY[]; @@ -646,11 +658,10 @@ extern const char STR_PERSISTENT_MAH[]; extern const char STR_USB_SERIAL[]; extern const char STR_SETUP_SCREENS[]; extern const char STR_MONITOR_SCREENS[]; -#endif extern const char STR_RESET_BTN[]; extern const char STR_DEBUG[]; -extern const char STR_SWITCHES_BTN[]; +extern const char STR_KEYS_BTN[]; extern const char STR_ANALOGS_BTN[]; extern const char STR_CALIB_BTN[]; @@ -682,7 +693,6 @@ extern const char STR_NIGHTLY_NOTSAFE[]; extern const char STR_WRONG_SDCARDVERSION[]; extern const char STR_WRONG_PCBREV[]; extern const char STR_EMERGENCY_MODE[]; -extern const char STR_PCBREV_ERROR[]; extern const char STR_NO_FAILSAFE[]; extern const char STR_KEYSTUCK[]; @@ -751,71 +761,72 @@ extern const char STR_FLASH_EXTERNAL_DEVICE[]; extern const char STR_FLASH_INTERNAL_MODULE[]; extern const char STR_FLASH_EXTERNAL_MODULE[]; extern const char STR_FIRMWARE_UPDATE_ERROR[]; -extern const char STR_WRITING[]; +extern const char STR_FIRMWARE_UPDATE_SUCCESS[]; extern const char STR_CONFIRM_FORMAT[]; -extern const char STR_EEBACKUP[]; -extern const char STR_FACTORYRESET[]; extern const char STR_CONFIRMRESET[]; extern const char STR_TOO_MANY_LUA_SCRIPTS[]; extern const char STR_BLCOLOR[]; - struct LanguagePack { - const char * id; - const char * name; - void (*playNumber)(getvalue_t number, uint8_t unit, uint8_t flags, uint8_t id); - void (*playDuration)(int seconds, uint8_t flags, uint8_t id); - }; +struct LanguagePack { + const char * id; + const char * name; + void (*playNumber)(getvalue_t number, uint8_t unit, uint8_t flags, uint8_t id); + void (*playDuration)(int seconds, uint8_t flags, uint8_t id); +}; - extern const LanguagePack * currentLanguagePack; - extern uint8_t currentLanguagePackIdx; +extern const LanguagePack * currentLanguagePack; +extern uint8_t currentLanguagePackIdx; + +extern const LanguagePack czLanguagePack; +extern const LanguagePack deLanguagePack; +extern const LanguagePack enLanguagePack; +extern const LanguagePack esLanguagePack; +extern const LanguagePack frLanguagePack; +extern const LanguagePack huLanguagePack; +extern const LanguagePack itLanguagePack; +extern const LanguagePack nlLanguagePack; +extern const LanguagePack plLanguagePack; +extern const LanguagePack ptLanguagePack; +extern const LanguagePack ruLanguagePack; +extern const LanguagePack seLanguagePack; +extern const LanguagePack skLanguagePack; +extern const LanguagePack * const languagePacks[]; + +#if defined(LANGUAGE_PACKS_DEFINITION) +const LanguagePack * const languagePacks[] = { + // alphabetical order + &czLanguagePack, + &deLanguagePack, + &enLanguagePack, + &esLanguagePack, + &frLanguagePack, + &huLanguagePack, + &itLanguagePack, + &nlLanguagePack, + &plLanguagePack, + &ptLanguagePack, + &ruLanguagePack, + &seLanguagePack, + &skLanguagePack, + NULL +}; +#endif - extern const LanguagePack czLanguagePack; - extern const LanguagePack deLanguagePack; - extern const LanguagePack enLanguagePack; - extern const LanguagePack esLanguagePack; - extern const LanguagePack frLanguagePack; - extern const LanguagePack huLanguagePack; - extern const LanguagePack itLanguagePack; - extern const LanguagePack nlLanguagePack; - extern const LanguagePack plLanguagePack; - extern const LanguagePack ptLanguagePack; - extern const LanguagePack ruLanguagePack; - extern const LanguagePack seLanguagePack; - extern const LanguagePack skLanguagePack; - extern const LanguagePack * const languagePacks[]; - #if defined(LANGUAGE_PACKS_DEFINITION) - const LanguagePack * const languagePacks[] = { - // alphabetical order - &czLanguagePack, - &deLanguagePack, - &enLanguagePack, - &esLanguagePack, - &frLanguagePack, - &huLanguagePack, - &itLanguagePack, - &nlLanguagePack, - &plLanguagePack, - &ptLanguagePack, - &ruLanguagePack, - &seLanguagePack, - &skLanguagePack, - NULL - }; - #endif #if defined(SIMU) #define LANGUAGE_PACK_DECLARE(lng, name) const LanguagePack lng ## LanguagePack = { #lng, name, lng ## _ ## playNumber, lng ## _ ## playDuration } #else #define LANGUAGE_PACK_DECLARE(lng, name) extern const LanguagePack lng ## LanguagePack = { #lng, name, lng ## _ ## playNumber, lng ## _ ## playDuration } #endif - #define LANGUAGE_PACK_DECLARE_DEFAULT(lng, name) LANGUAGE_PACK_DECLARE(lng, name); const LanguagePack * currentLanguagePack = & lng ## LanguagePack; uint8_t currentLanguagePackIdx - inline PLAY_FUNCTION(playNumber, getvalue_t number, uint8_t unit, uint8_t flags) { currentLanguagePack->playNumber(number, unit, flags, id); } - inline PLAY_FUNCTION(playDuration, int seconds, uint8_t flags) { currentLanguagePack->playDuration(seconds, flags, id); } - extern const char STR_MODELNAME[]; - extern const char STR_PHASENAME[]; - extern const char STR_MIXNAME[]; - extern const char STR_INPUTNAME[]; - extern const char STR_EXPONAME[]; +#define LANGUAGE_PACK_DECLARE_DEFAULT(lng, name) LANGUAGE_PACK_DECLARE(lng, name); const LanguagePack * currentLanguagePack = & lng ## LanguagePack; uint8_t currentLanguagePackIdx +inline PLAY_FUNCTION(playNumber, getvalue_t number, uint8_t unit, uint8_t flags) { currentLanguagePack->playNumber(number, unit, flags, id); } +inline PLAY_FUNCTION(playDuration, int seconds, uint8_t flags) { currentLanguagePack->playDuration(seconds, flags, id); } + +extern const char STR_MODELNAME[]; +extern const char STR_PHASENAME[]; +extern const char STR_MIXNAME[]; +extern const char STR_INPUTNAME[]; +extern const char STR_EXPONAME[]; #if defined(COLORLCD) #define TR_PHASES_HEADERS { TR_PHASES_HEADERS_NAME, TR_PHASES_HEADERS_SW, TR_PHASES_HEADERS_RUD_TRIM, TR_PHASES_HEADERS_ELE_TRIM, TR_PHASES_HEADERS_THT_TRIM, TR_PHASES_HEADERS_AIL_TRIM, TR_PHASES_HEADERS_CH5_TRIM, TR_PHASES_HEADERS_CH6_TRIM, TR_PHASES_HEADERS_FAD_IN, TR_PHASES_HEADERS_FAD_OUT } @@ -836,123 +847,127 @@ extern const char STR_BLCOLOR[]; #endif extern const char STR_TRAINER[]; - extern const char STR_MODULE_BIND[]; - extern const char STR_BINDING_1_8_TELEM_ON[]; - extern const char STR_BINDING_1_8_TELEM_OFF[]; - extern const char STR_BINDING_9_16_TELEM_ON[]; - extern const char STR_BINDING_9_16_TELEM_OFF[]; - extern const char STR_CHANNELRANGE[]; - extern const char STR_ANTENNASELECTION[]; - extern const char STR_ANTENNACONFIRM1[]; - extern const char STR_ANTENNACONFIRM2[]; - extern const char STR_R9MFLEXWARN1[]; - extern const char STR_R9MFLEXWARN2[]; - extern const char STR_SET[]; - extern const char STR_PREFLIGHT[]; - extern const char STR_CHECKLIST[]; - extern const char STR_VIEW_NOTES[]; - extern const char STR_MODEL_SELECT[]; - extern const char STR_RESET_SUBMENU[]; - extern const char STR_LOWALARM[]; - extern const char STR_CRITICALALARM[]; - extern const char STR_RSSIALARM_WARN[]; - extern const char STR_NO_RSSIALARM[]; - extern const char STR_DISABLE_ALARM[]; - extern const char STR_TELEMETRY_TYPE[]; - extern const char STR_TELEMETRY_SENSORS[]; - extern const char STR_VALUE[]; - extern const char STR_TOPLCDTIMER[]; - extern const char STR_UNIT[] ; - extern const char STR_TELEMETRY_NEWSENSOR[]; - extern const char STR_ID[]; - extern const char STR_PRECISION[]; - extern const char STR_RATIO[]; - extern const char STR_FORMULA[]; - extern const char STR_CELLINDEX[]; - extern const char STR_LOGS[]; - extern const char STR_OPTIONS[]; - extern const char STR_ALTSENSOR[]; - extern const char STR_CELLSENSOR[]; - extern const char STR_GPSSENSOR[]; - extern const char STR_CURRENTSENSOR[]; - extern const char STR_AUTOOFFSET[]; - extern const char STR_ONLYPOSITIVE[]; - extern const char STR_FILTER[]; - extern const char STR_TELEMETRYFULL[]; - extern const char STR_SERVOS_OK[]; - extern const char STR_SERVOS_KO[]; - extern const char STR_INVERTED_SERIAL[]; - extern const char STR_IGNORE_INSTANCE[]; - extern const char STR_DISCOVER_SENSORS[]; - extern const char STR_STOP_DISCOVER_SENSORS[]; - extern const char STR_DELETE_ALL_SENSORS[]; - extern const char STR_CONFIRMDELETE[]; - extern const char STR_SELECT_WIDGET[]; - extern const char STR_REMOVE_WIDGET[]; - extern const char STR_WIDGET_SETTINGS[]; - extern const char STR_REMOVE_SCREEN[]; - extern const char STR_SETUP_WIDGETS[]; - extern const char STR_USER_INTERFACE[]; - extern const char STR_THEME[]; - extern const char STR_SETUP[]; - extern const char STR_MAINVIEWX[]; - extern const char STR_LAYOUT[]; - extern const char STR_ADDMAINVIEW[]; - extern const char STR_BACKGROUND_COLOR[]; - extern const char STR_MAIN_COLOR[]; - extern const char STR_TEXT_VIEWER[]; - extern const char STR_MULTI_RFPOWER[]; +extern const char STR_MODULE_BIND[]; +extern const char STR_TRANSFER_BUTTON[]; +extern const char STR_REGISTER_BUTTON[]; +extern const char STR_RXADD_BUTTON[]; +extern const char STR_BINDING_1_8_TELEM_ON[]; +extern const char STR_BINDING_1_8_TELEM_OFF[]; +extern const char STR_BINDING_9_16_TELEM_ON[]; +extern const char STR_BINDING_9_16_TELEM_OFF[]; +extern const char STR_CHANNELRANGE[]; +extern const char STR_ANTENNASELECTION[]; +extern const char STR_ANTENNACONFIRM1[]; +extern const char STR_ANTENNACONFIRM2[]; +extern const char STR_R9MFLEXWARN1[]; +extern const char STR_R9MFLEXWARN2[]; +extern const char STR_SET[]; +extern const char STR_PREFLIGHT[]; +extern const char STR_CHECKLIST[]; +extern const char STR_VIEW_NOTES[]; +extern const char STR_MODEL_SELECT[]; +extern const char STR_RESET_SUBMENU[]; +extern const char STR_LOWALARM[]; +extern const char STR_CRITICALALARM[]; +extern const char STR_RSSIALARM_WARN[]; +extern const char STR_NO_RSSIALARM[]; +extern const char STR_DISABLE_ALARM[]; +extern const char STR_TELEMETRY_TYPE[]; +extern const char STR_TELEMETRY_SENSORS[]; +extern const char STR_VALUE[]; +extern const char STR_TOPLCDTIMER[]; +extern const char STR_UNIT[] ; +extern const char STR_TELEMETRY_NEWSENSOR[]; +extern const char STR_ID[]; +extern const char STR_PRECISION[]; +extern const char STR_RATIO[]; +extern const char STR_FORMULA[]; +extern const char STR_CELLINDEX[]; +extern const char STR_LOGS[]; +extern const char STR_OPTIONS[]; +extern const char STR_ALTSENSOR[]; +extern const char STR_CELLSENSOR[]; +extern const char STR_GPSSENSOR[]; +extern const char STR_CURRENTSENSOR[]; +extern const char STR_AUTOOFFSET[]; +extern const char STR_ONLYPOSITIVE[]; +extern const char STR_FILTER[]; +extern const char STR_TELEMETRYFULL[]; +extern const char STR_SERVOS_OK[]; +extern const char STR_SERVOS_KO[]; +extern const char STR_INVERTED_SERIAL[]; +extern const char STR_IGNORE_INSTANCE[]; +extern const char STR_DISCOVER_SENSORS[]; +extern const char STR_STOP_DISCOVER_SENSORS[]; +extern const char STR_DELETE_ALL_SENSORS[]; +extern const char STR_CONFIRMDELETE[]; +extern const char STR_SELECT_WIDGET[]; +extern const char STR_REMOVE_WIDGET[]; +extern const char STR_WIDGET_SETTINGS[]; +extern const char STR_REMOVE_SCREEN[]; +extern const char STR_SETUP_WIDGETS[]; +extern const char STR_USER_INTERFACE[]; +extern const char STR_THEME[]; +extern const char STR_SETUP[]; +extern const char STR_LAYOUT[]; +extern const char STR_ADDMAINVIEW[]; +extern const char STR_BACKGROUND_COLOR[]; +extern const char STR_MAIN_COLOR[]; +extern const char STR_TEXT_VIEWER[]; +extern const char STR_MULTI_RFPOWER[]; - extern const char STR_BYTES[]; - extern const char STR_ANTENNAPROBLEM[]; - extern const char STR_MODULE[]; - extern const char STR_ENABLE_POPUP[]; - extern const char STR_DISABLE_POPUP[]; - extern const char STR_POPUP[]; - extern const char STR_MIN[]; - extern const char STR_MAX[]; - extern const char STR_CURVE_PRESET[]; - extern const char STR_PRESET[]; - extern const char STR_MIRROR[]; - extern const char STR_CLEAR[]; - extern const char STR_RESET[]; - extern const char STR_COUNT[]; - extern const char STR_PT[]; - extern const char STR_PTS[]; - extern const char STR_SMOOTH[]; - extern const char STR_COPY_STICKS_TO_OFS[]; - extern const char STR_COPY_TRIMS_TO_OFS[]; - extern const char STR_INCDEC[]; - extern const char STR_GLOBALVAR[]; - extern const char STR_MIXSOURCE[]; - extern const char STR_CONSTANT[]; - extern const char STR_TOP_BAR[]; - extern const char STR_ALTITUDE[]; - extern const char STR_SCALE[]; - extern const char STR_VIEW_CHANNELS[]; - extern const char STR_POTWARNING[]; - extern const char STR_UART3MODE[]; - extern const char STR_THROTTLE_LABEL[]; - extern const char STR_SCRIPT[]; - extern const char STR_INPUTS[]; - extern const char STR_OUTPUTS[]; - extern const char STR_MENU_INPUTS[]; - extern const char STR_MENU_LUA[]; - extern const char STR_MENU_STICKS[]; - extern const char STR_MENU_POTS[]; - extern const char STR_MENU_MAX[]; - extern const char STR_MENU_HELI[]; - extern const char STR_MENU_TRIMS[]; - extern const char STR_MENU_SWITCHES[]; - extern const char STR_MENU_LOGICAL_SWITCHES[]; - extern const char STR_MENU_TRAINER[]; - extern const char STR_MENU_CHANNELS[]; - extern const char STR_MENU_GVARS[]; - extern const char STR_MENU_TELEMETRY[]; - 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_BYTES[]; +extern const char STR_ANTENNAPROBLEM[]; +extern const char STR_MODULE[]; +extern const char STR_RX_NAME[]; +extern const char STR_ENABLE_POPUP[]; +extern const char STR_DISABLE_POPUP[]; +extern const char STR_POPUP[]; +extern const char STR_MIN[]; +extern const char STR_MAX[]; +extern const char STR_CURVE_PRESET[]; +extern const char STR_PRESET[]; +extern const char STR_MIRROR[]; +extern const char STR_CLEAR[]; +extern const char STR_RESET[]; +extern const char STR_COUNT[]; +extern const char STR_PT[]; +extern const char STR_PTS[]; +extern const char STR_SMOOTH[]; +extern const char STR_COPY_STICKS_TO_OFS[]; +extern const char STR_COPY_TRIMS_TO_OFS[]; +extern const char STR_INCDEC[]; +extern const char STR_GLOBALVAR[]; +extern const char STR_MIXSOURCE[]; +extern const char STR_CONSTANT[]; +extern const char STR_TOP_BAR[]; +extern const char STR_ALTITUDE[]; +extern const char STR_SCALE[]; +extern const char STR_VIEW_CHANNELS[]; +extern const char STR_POTWARNING[]; +extern const char STR_UART3MODE[]; +extern const char STR_THROTTLE_LABEL[]; +extern const char STR_SCRIPT[]; +extern const char STR_INPUTS[]; +extern const char STR_OUTPUTS[]; +extern const char STR_MENU_INPUTS[]; +extern const char STR_MENU_LUA[]; +extern const char STR_MENU_STICKS[]; +extern const char STR_MENU_POTS[]; +extern const char STR_MENU_MAX[]; +extern const char STR_MENU_HELI[]; +extern const char STR_MENU_TRIMS[]; +extern const char STR_MENU_SWITCHES[]; +extern const char STR_MENU_LOGICAL_SWITCHES[]; +extern const char STR_MENU_TRAINER[]; +extern const char STR_MENU_CHANNELS[]; +extern const char STR_MENU_GVARS[]; +extern const char STR_MENU_TELEMETRY[]; +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_BUTTON_SHARE[]; #if MENUS_LOCK == 1 extern const char STR_UNLOCKED[]; @@ -960,57 +975,55 @@ extern const char STR_BLCOLOR[]; #endif #if defined(PCBTARANIS) || defined(DSM2) - extern const char STR_MODULE_RANGE[]; +extern const char STR_MODULE_RANGE[]; +extern const char STR_RECEIVER_OPTIONS[]; +extern const char STR_DEL_BUTTON[]; #endif +extern const char STR_ABOUTUS[]; +extern const char STR_ABOUT_OPENTX_1[]; +extern const char STR_ABOUT_OPENTX_2[]; +extern const char STR_ABOUT_OPENTX_3[]; +extern const char STR_ABOUT_OPENTX_4[]; +extern const char STR_ABOUT_OPENTX_5[]; - extern const char STR_ABOUTUS[]; - extern const char STR_ABOUT_OPENTX_1[]; - extern const char STR_ABOUT_OPENTX_2[]; - extern const char STR_ABOUT_OPENTX_3[]; - extern const char STR_ABOUT_OPENTX_4[]; - extern const char STR_ABOUT_OPENTX_5[]; +extern const char STR_ABOUT_BERTRAND_1[]; +extern const char STR_ABOUT_BERTRAND_2[]; +extern const char STR_ABOUT_BERTRAND_3[]; - extern const char STR_ABOUT_BERTRAND_1[]; - extern const char STR_ABOUT_BERTRAND_2[]; - extern const char STR_ABOUT_BERTRAND_3[]; +extern const char STR_ABOUT_MIKE_1[]; +extern const char STR_ABOUT_MIKE_2[]; +extern const char STR_ABOUT_MIKE_3[]; +extern const char STR_ABOUT_MIKE_4[]; - extern const char STR_ABOUT_MIKE_1[]; - extern const char STR_ABOUT_MIKE_2[]; - extern const char STR_ABOUT_MIKE_3[]; - extern const char STR_ABOUT_MIKE_4[]; +extern const char STR_ABOUT_ROMOLO_1[]; +extern const char STR_ABOUT_ROMOLO_2[]; +extern const char STR_ABOUT_ROMOLO_3[]; - extern const char STR_ABOUT_ROMOLO_1[]; - extern const char STR_ABOUT_ROMOLO_2[]; - extern const char STR_ABOUT_ROMOLO_3[]; +extern const char STR_ABOUT_ANDRE_1[]; +extern const char STR_ABOUT_ANDRE_2[]; +extern const char STR_ABOUT_ANDRE_3[]; - extern const char STR_ABOUT_ANDRE_1[]; - extern const char STR_ABOUT_ANDRE_2[]; - extern const char STR_ABOUT_ANDRE_3[]; +extern const char STR_ABOUT_ROB_1[]; +extern const char STR_ABOUT_ROB_2[]; - extern const char STR_ABOUT_ROB_1[]; - extern const char STR_ABOUT_ROB_2[]; +extern const char STR_ABOUT_MARTIN_1[]; +extern const char STR_ABOUT_MARTIN_2[]; - extern const char STR_ABOUT_MARTIN_1[]; - extern const char STR_ABOUT_MARTIN_2[]; +extern const char STR_ABOUT_KJELL_1[]; +extern const char STR_ABOUT_KJELL_2[]; +extern const char STR_ABOUT_KJELL_3[]; +extern const char STR_ABOUT_KJELL_4[]; - extern const char STR_ABOUT_KJELL_1[]; - extern const char STR_ABOUT_KJELL_2[]; - extern const char STR_ABOUT_KJELL_3[]; - extern const char STR_ABOUT_KJELL_4[]; +extern const char STR_ABOUT_HARDWARE_1[]; +extern const char STR_ABOUT_HARDWARE_2[]; +extern const char STR_ABOUT_HARDWARE_3[]; - extern const char STR_ABOUT_HARDWARE_1[]; - extern const char STR_ABOUT_HARDWARE_2[]; - extern const char STR_ABOUT_HARDWARE_3[]; +extern const char STR_ABOUT_PARENTS_1[]; +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_ABOUT_PARENTS_1[]; - extern const char STR_ABOUT_PARENTS_2[]; - extern const char STR_ABOUT_PARENTS_3[]; - extern const char STR_ABOUT_PARENTS_4[]; - -#define CHR_SHORT TR_CHR_SHORT -#define CHR_LONG TR_CHR_LONG -#define CHR_TOGGLE TR_CHR_TOGGLE #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 e98794833..e6b95aada 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -99,8 +99,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "Vyp\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Popup\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "Vyp\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (kabel)Spektrum\0 " @@ -149,7 +152,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -157,21 +160,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POZ""NEG" @@ -415,12 +408,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -537,9 +536,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #define TR_POPUPS_ENTER_EXIT TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -573,6 +573,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Spínač" #define TR_TRIMS "Trimy" #define TR_FADEIN "Přechod Zap" @@ -778,6 +779,8 @@ #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING TR("Bind...","Binding") #define TR_REBIND "Rebinding required" +#define TR_REG_OK "Registration ok" +#define TR_BIND_OK "Bind successful" #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" @@ -915,18 +918,23 @@ #define TR_FLASH_INTERNAL_MODULE TR("Flash vnitř. modulu", "Flash vnitřního modulu") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. modulu", "Flash externího zařízení") #define TR_FIRMWARE_UPDATE_ERROR TR("Chyba zápisu FW", "Chyba zápisu firmware") +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING TR3("\14Zapisuji..", "\032Zapisuji..", "Zapisuji..") #define TR_CONFIRM_FORMAT "Provést Formát?" #define TR_INTERNALRF "Vnitřní RF modul" #define TR_EXTERNALRF "Externí RF modul" #define TR_FAILSAFE TR("Failsafe", "Mód Failsafe") #define TR_FAILSAFESET "NASTAVENÍ FAILSAFE" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENZOR" #define TR_SENSOR "SENZOR" #define TR_COUNTRYCODE "Kód regionu" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Jazyk hlasu" #define TR_UNITSSYSTEM "Jednotky" #define TR_EDIT "Upravit" @@ -956,10 +964,16 @@ #define TR_BUZZER INDENT"Pípák" #define TR_BYTES "[B]" #define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind")) +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE BUTTON(TR("Rng", "Range")) +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN BUTTON("Reset") #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET BUTTON("Volby") @@ -967,6 +981,7 @@ #define TR_ANTENNAPROBLEM CENTER "Problém s TX anténou!" #define TR_MODELIDUSED TR("ID již použito","ID modelu je již použito") #define TR_MODULE INDENT "Modul" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Typ", "Typ telemetrie") #define TR_TELEMETRY_SENSORS "Senzory" #define TR_VALUE "Hodnota" @@ -1014,16 +1029,14 @@ #define TR_INPUTS "Vstupy" #define TR_OUTPUTS "Výstupy" #if defined(COLORLCD) -#define TR_EEBACKUP "Záloha EEPROM" -#define TR_FACTORYRESET "Factory reset" +#define STR_EEBACKUP "Záloha EEPROM" +#define STR_FACTORYRESET "Factory reset" #else -#define TR_EEBACKUP TR("[dlouze ENTER]: Záloha", "\010[dlouze ENTER] zálohuje EEPROM") -#define TR_FACTORYRESET TR("[dlouze MENU]: Fact.reset", "\012[dlouze MENU]: Factory reset") +#define STR_EEBACKUP TR("Záloha", "Zálohuje EEPROM") +#define STR_FACTORYRESET TR("Fact.reset", "Factory reset") #endif -#define TR_CONFIRMRESET "Smazat modely a nastavení?" -#define TR_TO_MANY_LUA_SCRIPTS "Příliš mnoho skriptů!" - - +#define STR_CONFIRMRESET "Smazat modely a nastavení?" +#define STR_TO_MANY_LUA_SCRIPTS "Příliš mnoho skriptů!" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Název" @@ -1196,6 +1209,7 @@ #define TR_JITTER_FILTER "ADC Filtr" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 52dce402d..f0b7ba845 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Fragen""Joyst\0""SDCard""Serial", "Fragen\0 ""Joystick""Speicher""Seriell\0") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Popup\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "AUS\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (Kabel)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -152,7 +155,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -160,21 +163,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -430,12 +423,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -543,9 +542,10 @@ #define TR_EXIT "[EXIT]" #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -578,6 +578,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Schalt.", "Schalter") #define TR_TRIMS "Trims" #define TR_FADEIN "Langs. Ein" @@ -783,6 +784,8 @@ #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_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" @@ -920,18 +923,23 @@ #define TR_FLASH_INTERNAL_MODULE TR("Flash int. XJT","Flash internes XJT-Modul") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash extern module") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_WRITING "\032Writing..." // +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" +#define STR_WRITING "Writing..." #define TR_CONFIRM_FORMAT "Formatieren bestätigen?" #define TR_INTERNALRF "Internes HF-Modul" #define TR_EXTERNALRF "Externes HF-Modul" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Mode") #define TR_FAILSAFESET "Failsafe setzen" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Landescode" #define TR_USBMODE "USB Modus" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Sprach-Ansagen" #define TR_UNITSSYSTEM "Einheiten" #define TR_EDIT "Zeile Editieren" @@ -961,10 +969,16 @@ #define TR_BUZZER INDENT "Summer" #define TR_BYTES "Bytes" #define TR_MODULE_BIND BUTTON(TR("Bnd","Bind")) //9XR-Pro +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE BUTTON(TR("Rng", "Range")) //9XR-Pro +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN BUTTON("Reset") #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET BUTTON("Set") @@ -972,6 +986,7 @@ #define TR_ANTENNAPROBLEM CENTER "TX-Antennenproblem!" #define TR_MODELIDUSED TR("ID schon benutzt", "Modell-ID schon benutzt") #define TR_MODULE INDENT "Modul-Typ" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Typ", "Telemetrietyp") #define TR_TELEMETRY_SENSORS "Sensoren" #define TR_VALUE "Wert" @@ -1018,8 +1033,8 @@ #define TR_SCRIPT "Lua-Skript" #define TR_INPUTS "Eingaben" #define TR_OUTPUTS "Ausgaben" -#define TR_EEBACKUP TR("[ENTER Long] EEPROM->SD"," [ENTER Long] Backup EEPROM->SD-Karte") -#define TR_FACTORYRESET TR("[MENU Long] Werksreset"," [MENU Long] Auf Werkseinstellungen") +#define STR_EEBACKUP TR("EEPROM->SD", "Backup EEPROM->SD-Karte") +#define STR_FACTORYRESET TR("Werksreset", "Auf Werkseinstellungen") #define TR_CONFIRMRESET TR("Alles löschen? ","ALLE Modelle+Einst. löschen?") #define TR_TO_MANY_LUA_SCRIPTS "Zu viele Lua-Skripte!" @@ -1194,6 +1209,7 @@ #define TR_JITTER_FILTER "ADC Filter" // ---------------------------------------------------------------- #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index f04ada9cd..a5847f726 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -151,7 +154,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -159,22 +162,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -420,12 +412,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -537,14 +535,17 @@ #if defined(PCBHORUS) #define TR_EXIT "[RTN]" + #define TR_OK TR_ENTER #else #define TR_EXIT "[EXIT]" + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #define TR_POPUPS_ENTER_EXIT TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -577,6 +578,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Switch" #define TR_TRIMS "Trims" #define TR_FADEIN "Fade in" @@ -782,6 +784,8 @@ #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING TR("Bind...","Binding") #define TR_REBIND "Rebinding required" +#define TR_REG_OK "Registration ok" +#define TR_BIND_OK "Bind successful" #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" @@ -803,7 +807,7 @@ #define TR_POWEROFF "\027Power OFF..." #define TR_SHUTDOWN "SHUTTING DOWN" #define TR_SAVEMODEL "Saving model settings" -#define TR_BATT_CALIB TR("Battery calib", "Battery calibration") +#define TR_BATT_CALIB TR("Batt. calib", "Battery calibration") #define TR_CURRENT_CALIB "Current calib" #define TR_VOLTAGE TR(INDENT "Voltage", INDENT "Voltage source") #define TR_CURRENT TR(INDENT "Current", INDENT "Current source") @@ -919,18 +923,23 @@ #define TR_FLASH_INTERNAL_MODULE TR("Flash int. module", "Flash internal module") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. module", "Flash external module") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update error", "Firmware update error") -#define TR_WRITING TR3("\14Writing...", "\032Writing...", "Writing...") +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" +#define STR_WRITING "Writing..." #define TR_CONFIRM_FORMAT "Confirm Format?" #define TR_INTERNALRF "Internal RF" #define TR_EXTERNALRF "External RF" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe mode") #define TR_FAILSAFESET "FAILSAFE SETTINGS" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Country code" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Voice language" #define TR_UNITSSYSTEM "Units" #define TR_EDIT "Edit" @@ -960,11 +969,17 @@ #define TR_BUZZER INDENT "Buzzer" #define TR_BYTES "bytes" #define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind")) +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON BUTTON("Add") #define TR_MODULE_RANGE BUTTON(TR("Rng", "Range")) +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN BUTTON("Reset") #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) -#define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) +#define TR_KEYS_BTN BUTTON(TR("Keys", "Switches")) +#define TR_ANALOGS_BTN BUTTON(TR("Anas", "Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET BUTTON("Set") #define TR_TRAINER "Trainer" @@ -975,6 +990,7 @@ #define TR_MODELIDUSED TR("ID used in:","Receiver ID used in:") #endif #define TR_MODULE INDENT "Module" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type", "Telemetry type") #define TR_TELEMETRY_SENSORS "Sensors" #define TR_VALUE "Value" @@ -1021,20 +1037,11 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Inputs" #define TR_OUTPUTS "Outputs" -#if defined(COLORLCD) -#define TR_EEBACKUP "EEPROM backup" -#define TR_FACTORYRESET "Factory reset" -#elif defined(PCBXLITE) -#define TR_EEBACKUP "\001[ENT. Long]: Backup" -#define TR_FACTORYRESET "\001[\300ENT. Long]: Fact. reset" -#else -#define TR_EEBACKUP TR("\001[ENTER Long]: Backup", "\012[ENTER Long]: EEPROM backup") -#define TR_FACTORYRESET TR("\001[MENU Long]: Fact. reset", "\012[MENU Long]: Factory reset") -#endif +#define STR_EEBACKUP "EEPROM backup" +#define STR_FACTORYRESET "Factory reset" #define TR_CONFIRMRESET TR("Erase ALL", "Erase ALL models and settings?") #define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!" - // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Name" #define TR_PHASES_HEADERS_SW "Switch" @@ -1205,6 +1212,7 @@ #define TR_JITTER_FILTER "ADC filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index a00d60d29..231d43006 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -151,7 +154,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -159,21 +162,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -419,12 +412,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -541,9 +540,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -581,6 +581,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Interr" #define TR_TRIMS "Trims" #define TR_FADEIN "Inicio" @@ -789,6 +790,8 @@ #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_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" @@ -926,18 +929,23 @@ #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_WRITING "\032Writing..." +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" +#define STR_WRITING "Writing..." #define TR_CONFIRM_FORMAT "Confirm Format?" #define TR_INTERNALRF "Interna RF" #define TR_EXTERNALRF "Externa RF" #define TR_FAILSAFE INDENT"Modo sgdad." #define TR_FAILSAFESET "AJUSTES SGDAD." +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Codigo Pais" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Idioma voces" #define TR_UNITSSYSTEM "Unidades" #define TR_EDIT "Editar" @@ -967,10 +975,16 @@ #define TR_BUZZER INDENT"Zumbador" #define TR_BYTES "bytes" #define TR_MODULE_BIND "[Enlace]" +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE "[Limites]" +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Ajuste]" @@ -978,6 +992,7 @@ #define TR_ANTENNAPROBLEM CENTER "¡Problema antena TX!" #define TR_MODELIDUSED TR("ID en uso", "ID modelo en uso") #define TR_MODULE INDENT "Modulo" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type") #define TR_TELEMETRY_SENSORS "Sensors" #define TR_VALUE "Value" @@ -1024,8 +1039,8 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Inputs" #define TR_OUTPUTS "Outputs" -#define TR_EEBACKUP "\004[ENTER Long] to backup the EEPROM" -#define TR_FACTORYRESET "\012[MENU Long]: Factory reset" +#define STR_EEBACKUP "Backup the EEPROM" +#define STR_FACTORYRESET "Factory reset" #define TR_CONFIRMRESET "Erase ALL models and settings?" #define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!" @@ -1200,6 +1215,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 818aaa110..b3226e134 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -151,7 +154,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -159,21 +162,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -419,12 +412,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -533,9 +532,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -573,6 +573,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Switch" #define TR_TRIMS "Trims" #define TR_FADEIN "Fade In" @@ -781,6 +782,8 @@ #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_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" @@ -918,18 +921,23 @@ #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_WRITING "\032Writing..." +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" +#define TR_WRITING "Writing..." #define TR_CONFIRM_FORMAT "Confirm Format?" #define TR_INTERNALRF "Internal RF" #define TR_EXTERNALRF "External RF" #define TR_FAILSAFE INDENT "Failsafe mode" #define TR_FAILSAFESET "FAILSAFE SETTINGS" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Country Code" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Voice Language" #define TR_UNITSSYSTEM "Units" #define TR_EDIT "Edit" @@ -959,10 +967,16 @@ #define TR_BUZZER INDENT"Buzzer" #define TR_BYTES "bytes" #define TR_MODULE_BIND "[Bind]" +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE "[Range]" +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Set]" @@ -970,6 +984,7 @@ #define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!" #define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:") #define TR_MODULE INDENT "Module" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type") #define TR_TELEMETRY_SENSORS "Sensors" #define TR_VALUE "Value" @@ -1016,8 +1031,8 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Inputs" #define TR_OUTPUTS "Outputs" -#define TR_EEBACKUP "\004[ENTER Long] to backup the EEPROM" -#define TR_FACTORYRESET "\012[MENU Long]: Factory reset" +#define STR_EEBACKUP "Backup the EEPROM" +#define STR_FACTORYRESET "Factory reset" #define TR_CONFIRMRESET "Erase ALL models and settings?" #define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!" @@ -1186,6 +1201,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index cf2b657fe..9045b18fd 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Popup\0""Joyst\0""SDCard""Série\0", "Demander""Joystick""Stockage""Série\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -151,7 +154,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -159,21 +162,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SLV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -432,12 +425,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -554,9 +553,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #define TR_POPUPS_ENTER_EXIT TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -590,6 +590,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Inter", "Interrupteur") #define TR_TRIMS "Trims" #define TR_FADEIN "Fondu ON" @@ -794,6 +795,8 @@ #define TR_MODULE_WAITFORBIND "Binder d'abord" #define TR_MODULE_BINDING "Bind..." #define TR_REBIND "Rebinding required" +#define TR_REG_OK "Registration ok" +#define TR_BIND_OK "Bind successful" #define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Télem ON" #define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Télem OFF" #define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Télem ON" @@ -930,18 +933,23 @@ #define TR_FLASH_INTERNAL_MODULE TR("Flasher module int.", "Flasher module interne") #define TR_FLASH_EXTERNAL_MODULE TR("Flasher module ext.", "Flasher module externe") #define TR_FIRMWARE_UPDATE_ERROR TR("Erreur màj FW","Erreur de mise à jour") +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING TR("\14Ecriture...", "\032Ecriture...") #define TR_CONFIRM_FORMAT "Confirmer Formatage?" #define TR_INTERNALRF "HF interne" #define TR_EXTERNALRF "HF externe" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Type failsafe") #define TR_FAILSAFESET "REGLAGES FAILSAFE" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "CAPTEUR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE TR("Zone géo.", "Zone géographique") #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG TR("Langue voix", "Langue annonces vocales") #define TR_UNITSSYSTEM "Unités" #define TR_EDIT "Editer" @@ -971,17 +979,24 @@ #define TR_BUZZER INDENT "Bipeur" #define TR_BYTES "bytes" #define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind")) +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE BUTTON(TR("Prt", "Port.")) +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN BUTTON("RAZ") #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) -#define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) +#define TR_KEYS_BTN BUTTON(TR("Swtchs", "Switches")) +#define TR_ANALOGS_BTN BUTTON(TR("Anas", "Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET BUTTON("Déf") #define TR_TRAINER "Ecolage" #define TR_ANTENNAPROBLEM CENTER "Antenne radio défectueuse!" #define TR_MODELIDUSED TR("ID affecté à :", "No de récepteur utilisé par :") #define TR_MODULE INDENT "Type de module" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type tél.", "Type télémétrie") #define TR_TELEMETRY_SENSORS "Capteurs" #define TR_VALUE "Valeur" @@ -1029,19 +1044,18 @@ #define TR_INPUTS "Entrées" #define TR_OUTPUTS "Sorties" #if defined(COLORLCD) -#define TR_EEBACKUP "Sauvegarder l'EEPROM" -#define TR_FACTORYRESET "RAZ d'usine" +#define STR_EEBACKUP "Sauvegarder l'EEPROM" +#define STR_FACTORYRESET "RAZ d'usine" #elif defined(PCBXLITE) -#define TR_EEBACKUP "[ENTER Long]:Sauvegarde" -#define TR_FACTORYRESET "[\300ENTER Long]: RAZ usine" +#define STR_EEBACKUP "Sauvegarde" +#define STR_FACTORYRESET "RAZ usine" #else -#define TR_EEBACKUP TR("[ENTER Long]:Sauvegarde", "\004[ENTER Long]: Sauvegarder l'EEPROM") -#define TR_FACTORYRESET TR("\001[MENU Long]: RAZ d'usine", "\016[MENU Long]: RAZ d'usine") +#define STR_EEBACKUP TR("Sauvegarde", "Sauvegarder l'EEPROM") +#define STR_FACTORYRESET "RAZ d'usine" #endif #define TR_CONFIRMRESET TR("Effacer TOUT?","Effacer TOUS modèles/réglages?") #define TR_TO_MANY_LUA_SCRIPTS "Trop de scripts lua!" - // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nom" #define TR_PHASES_HEADERS_SW "Inter" @@ -1212,6 +1226,7 @@ #define TR_JITTER_FILTER "Filtre ADC" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 83d79217b..5b2730408 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -151,7 +154,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -159,21 +162,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -421,12 +414,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -543,9 +542,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -579,6 +579,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Inter." #define TR_TRIMS "Trims" #define TR_FADEIN "Diss.In" @@ -783,6 +784,8 @@ #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_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" @@ -920,18 +923,23 @@ #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_INTERNALRF "Modulo Interno" #define TR_EXTERNALRF "Modulo esterno" #define TR_FAILSAFE "Modo failsafe" #define TR_FAILSAFESET TR("FAILSAFE","IMPOSTAZIONI FAILSAFE") +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE TR("Codice Paese","Standard 2.4Ghz") #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Lingua Voce" #define TR_UNITSSYSTEM "Unità" #define TR_EDIT "Modifica" @@ -961,10 +969,16 @@ #define TR_BUZZER INDENT"Buzzer" #define TR_BYTES "Bytes" #define TR_MODULE_BIND "[Bind]" +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE "[Range]" +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Set]" @@ -972,6 +986,7 @@ #define TR_ANTENNAPROBLEM CENTER "Problemi antenna TX!" #define TR_MODELIDUSED TR("ID già usato","ID Modello già usato") #define TR_MODULE INDENT "Modulo" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE "Tipo Telemetria" #define TR_TELEMETRY_SENSORS "Sensori" #define TR_VALUE "Valore" @@ -1018,8 +1033,8 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Ingresso" #define TR_OUTPUTS "Uscita" -#define TR_EEBACKUP "\004[ENTER Lungo] per copiare la EEPROM" -#define TR_FACTORYRESET "\012[MENU Lungo]: Inizializza dati" +#define STR_EEBACKUP "Copiare la EEPROM" +#define STR_FACTORYRESET "Inizializza dati" #define TR_CONFIRMRESET "Resettare TUTTI i dati?" #define TR_TO_MANY_LUA_SCRIPTS "Troppi Scripts Lua!" @@ -1195,6 +1210,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index c5774188e..2671ca6fb 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -103,8 +103,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Popup\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "UIT\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -153,7 +156,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -161,21 +164,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -414,12 +407,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -538,9 +537,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -573,6 +573,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH TR("Schak.", "Schakelaar") #define TR_TRIMS "Trims" #define TR_FADEIN "Fade in" @@ -784,6 +785,8 @@ #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_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" @@ -921,18 +924,23 @@ #define TR_FLASH_INTERNAL_MODULE "Flash interne XJT-Module" #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 "\032Schrijven..." #define TR_CONFIRM_FORMAT "Formatteren bevestigen?" #define TR_INTERNALRF "Interne RF" #define TR_EXTERNALRF "Externe RF" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafe Modus") #define TR_FAILSAFESET "Failsafe instellen" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Landcode" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Taal" #define TR_UNITSSYSTEM "Eenheden" #define TR_EDIT "Wijzigen" @@ -962,10 +970,16 @@ #define TR_BUZZER INDENT "Zoemer" #define TR_BYTES "bytes" #define TR_MODULE_BIND TR("[Bnd]", "[Bind]") +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE TR("[Rng]", "[Range]") +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Set]" @@ -973,6 +987,7 @@ #define TR_ANTENNAPROBLEM CENTER "TX-Antenneprobleem!" #define TR_MODELIDUSED TR("ID al gebruikt", "Model-ID al gebruikt") #define TR_MODULE INDENT "Module-Type" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type", "Telemetrietype") #define TR_TELEMETRY_SENSORS "Sensoren" #define TR_VALUE "Waarde" @@ -1020,11 +1035,11 @@ #define TR_INPUTS "Inputs" #define TR_OUTPUTS "Outputs" #if defined(COLORLCD) -#define TR_EEBACKUP "EEPROM backup" -#define TR_FACTORYRESET "Factory reset" +#define STR_EEBACKUP "EEPROM backup" +#define STR_FACTORYRESET "Factory reset" #else -#define TR_EEBACKUP TR("\001[ENTER Lang]: Backup", "\012[ENTER Lang]: EEPROM backup => SD") -#define TR_FACTORYRESET TR("\001[MENU Lang]: Fact. reset", "\012[MENU Lang]: Factory reset") +#define STR_EEBACKUP TR("Backup", "EEPROM backup => SD") +#define STR_FACTORYRESET TR("Fact. reset", "Factory reset") #endif #define TR_CONFIRMRESET TR("Wis Alles?", "Wis ALLE modellen en instellingen?") @@ -1202,6 +1217,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index ed2a754c9..b31b60316 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -152,7 +155,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -160,21 +163,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POZ""NEG" @@ -422,12 +415,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -544,9 +543,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -580,6 +580,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Przełą" #define TR_TRIMS "Trymy" #define TR_FADEIN "Pojawia" @@ -784,6 +785,8 @@ #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_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" @@ -921,18 +924,23 @@ #define TR_FLASH_INTERNAL_MODULE "Sflashuj Moduł Wewnętrzny" #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 "\032Zapis... " #define TR_CONFIRM_FORMAT "Zatwierdź Format?" #define TR_INTERNALRF "Wewn.Moduł RF" #define TR_EXTERNALRF "Zewn.Moduł RF" #define TR_FAILSAFE TR(INDENT"Failsafe",INDENT"Tryb Failsafe") #define TR_FAILSAFESET "USTAWIENIE FAILSAFE" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "CZUJNIK" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Kod regionu" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Język głosu" #define TR_UNITSSYSTEM "Jednostki" #define TR_EDIT "Edytuj" @@ -962,10 +970,16 @@ #define TR_BUZZER INDENT"Brzęczyk" #define TR_BYTES "bajty" #define TR_MODULE_BIND TR("[BND]","[Bind]") +#define TR_TRANSFER_BUTTON BUTTON("Transfert) +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE TR("[Zas]","Zasięg") +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Set]" @@ -973,6 +987,7 @@ #define TR_ANTENNAPROBLEM CENTER "Problem z anteną TX" #define TR_MODELIDUSED TR("ID zajęte","ID modelu zajęte") #define TR_MODULE INDENT "Moduł " +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Typ ", "Typ Telemetrii") #define TR_TELEMETRY_SENSORS "Czujniki" #define TR_VALUE "Wartość" @@ -1019,8 +1034,8 @@ #define TR_SCRIPT "Skrypt" #define TR_INPUTS "Wejścia" #define TR_OUTPUTS "Wyjścia" -#define TR_EEBACKUP "\012[ENTER Długo] Backup EEPROMu" -#define TR_FACTORYRESET "\012[MENU Long]: Ustaw.Fabrycz" +#define STR_EEBACKUP "Backup EEPROMu" +#define STR_FACTORYRESET "Ustaw.Fabrycz" #define TR_CONFIRMRESET "WYkasować wszytkie modele? " #define TR_TO_MANY_LUA_SCRIPTS "Za dużo skryptów Lua!" @@ -1196,6 +1211,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index fe87fcff8..6c5b90e30 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Popup\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -150,7 +153,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -158,21 +161,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - - #define TR_XPPM - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "POS""NEG" @@ -418,12 +411,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -540,9 +539,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -580,6 +580,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Chave" #define TR_TRIMS "Trims" #define TR_FADEIN "Aparecer" @@ -789,6 +790,8 @@ #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_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" @@ -925,18 +928,23 @@ #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_WRITING "\032Writing..." +#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" +#define STR_WRITING "Writing..." #define TR_CONFIRM_FORMAT "Confirm Format?" #define TR_INTERNALRF "Internal RF" #define TR_EXTERNALRF "External RF" #define TR_FAILSAFE "Failsafe mode" #define TR_FAILSAFESET "FAILSAFE SETTINGS" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Country Code" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Voice Language" #define TR_UNITSSYSTEM "Units" #define TR_EDIT "Edit" @@ -966,10 +974,16 @@ #define TR_BUZZER INDENT"Buzzer" #define TR_BYTES "bytes" #define TR_MODULE_BIND "[Bind]" +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE "[Range]" +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Set]" @@ -977,6 +991,7 @@ #define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!" #define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:") #define TR_MODULE INDENT "Module" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type") #define TR_TELEMETRY_SENSORS "Sensors" #define TR_VALUE "Value" @@ -1023,8 +1038,8 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Inputs" #define TR_OUTPUTS "Outputs" -#define TR_EEBACKUP "\004[ENTER Long] to backup the EEPROM" -#define TR_FACTORYRESET "\012[MENU Long]: Factory reset" +#define STR_EEBACKUP "Backup the EEPROM" +#define STR_FACTORYRESET "Factory reset" #define TR_CONFIRMRESET "Erase ALL models and settings?" #define TR_TO_MANY_LUA_SCRIPTS "Too many Lua scripts!" @@ -1199,6 +1214,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 9e3e6f898..8eee8f3f6 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -101,8 +101,11 @@ #define LEN_USBMODES TR("\006", "\010") #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") -#define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" +#define LEN_JACKMODES "\007" +#define TR_JACKMODES "Ask\0 ""Audio\0 ""Trainer" + +#define LEN_TARANIS_PROTOCOLS "\005" +#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0 ""XJT\0 ""XJT2\0""DSM2\0""CRSF\0""MULT\0""R9M\0 ""R9M2\0""R9LT\0""R9LT2""R9LP2""SBUS\0" #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" @@ -149,7 +152,7 @@ #if defined(PXX) #define TR_PXX "PXX\0 " -#elif defined(DSM2) || defined(IRPROTOS) +#elif defined(DSM2) #define TR_PXX "[PXX]\0" #else #define TR_PXX @@ -157,19 +160,11 @@ #if defined(DSM2) #define TR_DSM2 "LP45\0 ""DSM2\0 ""DSMX\0 " -#elif defined(IRPROTOS) - #define TR_DSM2 "[LP45]""[DSM2]""[DSMX]" #else #define TR_DSM2 #endif -#if defined(IRPROTOS) - #define TR_IRPROTOS "SILV TRAC09PICZ SWIFT\0" -#else - #define TR_IRPROTOS -#endif - -#define TR_VPROTOS "PPM\0 " TR_XPPM TR_PXX TR_DSM2 TR_IRPROTOS +#define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 #define LEN_POSNEG "\003" #define TR_POSNEG "Pos""Neg" @@ -426,12 +421,18 @@ #elif defined(PCBX9E) #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(PCBXLITES) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SF\0""\312SH\0" +#elif defined(PCBX3) + #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 "\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" @@ -550,9 +551,10 @@ #endif #if defined(PCBTARANIS) - #define TR_POPUPS TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_POPUPS_ENTER_EXIT TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER + #define TR_OK TR("\010" "\010" "\010" "[OK]", "\010" "\010" "\010" "\010" "\010" "[OK]") #else - #define TR_POPUPS TR_ENTER "\010" TR_EXIT + #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define OFS_EXIT sizeof(TR_ENTER) #endif @@ -590,6 +592,7 @@ #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_MS "ms" +#define TR_FREQUENCY INDENT "Frequency" #define TR_SWITCH "Brytare" #define TR_TRIMS "Trimmar" #define TR_FADEIN "Tona In" @@ -795,6 +798,8 @@ #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_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" @@ -932,18 +937,23 @@ #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #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 "\032Skriver..." #define TR_CONFIRM_FORMAT "Formatera Minnet?" #define TR_INTERNALRF "Intern Radio" #define TR_EXTERNALRF "Extern Radiomodul" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Failsafeläge") #define TR_FAILSAFESET "FailsafeInställning" +#define TR_REG_ID TR("Reg. ID", "Registration ID") +#define TR_OWNER_ID "Owner ID" +#define TR_PINMAPSET "PINMAP" #define TR_HOLD "HOLD" #define TR_NONE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_SENSOR "SENSOR" #define TR_COUNTRYCODE "Landskod" #define TR_USBMODE "USB Mode" +#define TR_JACKMODE "Jack Mode" #define TR_VOICELANG "Röstspråk" #define TR_UNITSSYSTEM "Enheter" #define TR_EDIT "Redigera" @@ -973,10 +983,16 @@ #define TR_BUZZER INDENT"Summer" #define TR_BYTES "byte" #define TR_MODULE_BIND TR("[Bnd]", "[Bind]") +#define TR_TRANSFER_BUTTON BUTTON("Transfer") +#define TR_REGISTER_BUTTON BUTTON(TR("Reg", "Register")) +#define TR_RXADD_BUTTON "BUTTON(Add)" #define TR_MODULE_RANGE TR("[Tst]", "[Testa]") +#define TR_BUTTON_SHARE BUTTON("Share") +#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") +#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) #define TR_RESET_BTN "[Nollställ]" #define TR_DEBUG "Debug" -#define TR_SWITCHES_BTN BUTTON(TR("SW","Switches")) +#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) #define TR_CALIB_BTN BUTTON("Calibration") #define TR_SET "[Spara]" @@ -984,6 +1000,7 @@ #define TR_ANTENNAPROBLEM CENTER "Fel på TX-antennen" #define TR_MODELIDUSED TR("ID finns redan","ModellID används redan") #define TR_MODULE INDENT "Modul" +#define TR_RX_NAME "Rx Name" #define TR_TELEMETRY_TYPE "Telemetrityp" #define TR_TELEMETRY_SENSORS "Sensorer" #define TR_VALUE "Värde" @@ -1030,8 +1047,8 @@ #define TR_SCRIPT "Programkod" #define TR_INPUTS "Input" #define TR_OUTPUTS "Outputs" -#define TR_EEBACKUP "\004[ENTER Lång] säkerhetskopiera EEPROM" -#define TR_FACTORYRESET "\012[MENU Long]: Factory reset" +#define TR_EEBACKUP "Säkerhetskopiera EEPROM" +#define TR_FACTORYRESET "Factory reset" #define TR_CONFIRMRESET "Erase ALL models and settings?" #define TR_TO_MANY_LUA_SCRIPTS "För många Lua-scripts!" @@ -1207,6 +1224,7 @@ #define TR_JITTER_FILTER "ADC Filter" #define ZSTR_RSSI "RSSI" +#define ZSTR_R9PW "R9PW" #define ZSTR_RAS "SWR" #define ZSTR_A1 "A1" #define ZSTR_A2 "A2" diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py index b990212e1..a48fb7c22 100755 --- a/radio/util/fwoptions.py +++ b/radio/util/fwoptions.py @@ -81,7 +81,6 @@ options_taranis = { "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_taranisplus = { @@ -99,7 +98,6 @@ options_taranisplus = { "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_xlite = { @@ -116,7 +114,6 @@ options_xlite = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), "stdr9m": ("MODULE_R9M_FULLSIZE", "YES", None), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_taranisx9e = { @@ -134,7 +131,6 @@ options_taranisx9e = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "horussticks": ("STICKS", "HORUS", "STANDARD"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_x12s = { @@ -149,7 +145,6 @@ options_x12s = { "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), "pcbdev": ("PCBREV", "10", None), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } options_x10 = { @@ -163,5 +158,4 @@ options_x10 = { "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "multimodule": ("MULTIMODULE", "YES", "NO"), - "flexr9m": ("MODULE_R9M_FLEX_FW", "YES", None) } diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index 70d54f240..51d4d235b 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -87,6 +87,15 @@ if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} fi +if [[ " X3 ALL " =~ " ${FLAVOR} " ]] ; then + # OpenTX on X3 + rm -rf * + cmake ${COMMON_OPTIONS} -DPCB=X3 -DHELI=YES -DGVARS=YES ${SRCDIR} + make -j${CORES} ${FIRMARE_TARGET} + make -j${CORES} libsimulator + make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} +fi + if [[ " X7 ALL " =~ " ${FLAVOR} " ]] ; then # OpenTX on X7 rm -rf * @@ -105,6 +114,15 @@ if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} fi +if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then + # OpenTX on X-Lites + rm -rf * + cmake ${COMMON_OPTIONS} -DPCB=XLITES -DHELI=YES -DGVARS=YES ${SRCDIR} + make -j${CORES} ${FIRMARE_TARGET} + make -j${CORES} libsimulator + make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} +fi + if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then # OpenTX on X9D rm -rf *