diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C123X.png b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C123X.png new file mode 100644 index 0000000000000000000000000000000000000000..133f0144e5ee83bb18501b825da91fb668ab49fe Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C123X.png differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C129X.png b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C129X.png new file mode 100644 index 0000000000000000000000000000000000000000..69bc11c46677eb3c47884a5ac805e970243b8598 Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TM4C129X.png differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TivaWare.png b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TivaWare.png new file mode 100644 index 0000000000000000000000000000000000000000..f2989d089ce239f963e0ddecbd71f7efbaa56307 Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/TivaWare.png differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c123g.jpg b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c123g.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74908c2d04f9710df4a717e54fe4d5ed32617a3e Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c123g.jpg differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c129x.jpg b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c129x.jpg new file mode 100644 index 0000000000000000000000000000000000000000..88c683b64ec5cf8d3fdd4f9d5b9a9e1421c9bcab Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/dk-tm4c129x.jpg differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c123gxl.jpg b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c123gxl.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a38f88aa2ab1becc796a0a2421ab16665aa0bcd4 Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c123gxl.jpg differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c1294xl.jpg b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c1294xl.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce34f3a0c01defc62cbc376bc01f91ae1f22274e Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/.metadata/images/ek-tm4c1294xl.jpg differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/EULA.txt b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/EULA.txt new file mode 100644 index 0000000000000000000000000000000000000000..87aec68bbe12afbdf517315fe04c5dcb7ea4cb08 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/EULA.txt @@ -0,0 +1,353 @@ +TI TivaWare for C Series Source and Object Code Software License Agreement + +IMPORTANT - PLEASE READ THE FOLLOWING LICENSE AGREEMENT CAREFULLY. THIS IS A +LEGALLY BINDING AGREEMENT. AFTER YOU READ THIS LICENSE AGREEMENT, YOU WILL BE +ASKED WHETHER YOU ACCEPT AND AGREE TO THE TERMS OF THIS LICENSE AGREEMENT. DO +NOT CLICK "I HAVE READ AND AGREE" UNLESS: (1) YOU ARE AUTHORIZED TO ACCEPT AND +AGREE TO THE TERMS OF THIS LICENSE AGREEMENT ON BEHALF OF YOURSELF OR YOUR +COMPANY (AS APPLICABLE); AND (2) YOU INTEND TO BE BOUND BY THE TERMS OF THIS +LICENSE AGREEMENT ON BEHALF OF YOURSELF OR YOUR COMPANY (AS APPLICABLE). + +Important - Read carefully: This Source and Object Code Software License +Agreement ("Agreement") is a legal agreement between you (either an individual +or legal entity) and Texas Instruments Incorporated ("TI"). The "Licensed +Materials" subject to this Agreement include the software programs (in whole or +in part) that accompany this Agreement [and set forth in the applicable +software manifest] and which you access "on-line" and/or electronic +documentation (in whole or in part) associated and provided with these software +programs, as well as any updates or upgrades to such software programs and +documentation, if any, provided to you at TI's sole discretion. The Licensed +Materials are specifically designed and licensed for use solely and exclusively +with semiconductor devices manufactured by or for TI ("TI Devices"). By +installing, copying or otherwise using the Licensed Materials you agree to +abide by the provisions set forth herein. This Agreement is displayed for you +to read prior to using the Licensed Materials. If you choose not to accept or +agree with these provisions, do not download or install the Licensed Materials. + +Note Regarding Possible Access to Open Source Software: The Licensed Materials +may be bundled with Open Source Software. "Open Source Software" means any +software licensed under terms requiring that (A) other software ("Proprietary +Software") incorporated, combined or distributed with such software or +developed using such software: (i) be disclosed or distributed in source code +form; or (ii) otherwise be licensed on terms inconsistent with the terms of +this Agreement, including but not limited to permitting use of the Proprietary +Software on or with devices other than TI Devices, or (B) require the owner of +Proprietary Software to license any of its patents to users of the Open Source +Software and/or Proprietary Software incorporated, combined or distributed with +such Open Source Software or developed using such Open Source Software. + +By accepting this Agreement, you may gain access to Open Source Software, in +which case such Open Source Software will be listed in the applicable software +manifest (in whole or in part, the "Open Source Materials"). Your use of the +Open Source Materials is subject to the separate licensing terms applicable to +such Open Source Materials as specified in the applicable software manifest. +For clarification, this Agreement does not limit your rights under, or grant +you rights that supersede, the license terms of any applicable Open Source +Materials license agreement. If any of the Open Source Materials have been +provided to you in object code only, TI will provide to you, or show you where +you can access, the source code versions of such Open Source Materials if you +contact TI at Texas Instruments Incorporated, 12500 TI Boulevard, Mail Station +8638, Dallas, Texas 75243, Attention: Contracts Manager, Embedded Processing. +In the event you choose not to accept or agree with the terms in any applicable +Open Source Materials license agreement, you must terminate this Agreement. + +1. License Grant and Use Restrictions. + +a. Licensed Materials License Grant. Subject to the terms of this Agreement, TI +hereby grants to you a limited, non-transferable, non-exclusive, +non-assignable, non-sub-licensable, fully paid-up and royalty-free license to: + +(i). Limited Source Code License. make copies, prepare derivative works, +display internally and use internally the Licensed Materials provided to you in +source code for the sole purpose of developing object and executable versions +of such Licensed Materials, or any derivative thereof, that execute solely and +exclusively on TI Devices, for end use in Licensee Products, and maintaining +and supporting such Licensed Materials, or any derivative thereof, and Licensee +Products. For purposes of this Agreement, "Licensee Product" means a product +that consists of both hardware, including one or more TI Devices, and software +components, including only executable versions of the Licensed Materials that +execute solely and exclusively on such TI Devices. + +(ii). Object Code Evaluation, Testing and Use License. make copies, display +internally, distribute internally and use internally the Licensed Materials in +object code for the sole purposes of evaluating and testing the Licensed +Materials and designing and developing Licensee Products, and maintaining and +supporting the Licensee Products; + +(iii). Demonstration License. demonstrate to third parties the Licensed +Materials executing solely and exclusively on TI Devices as they are used in +Licensee Products, provided that such Licensed Materials are demonstrated in +object or executable versions only and + +(iv). Production and Distribution License. make, use, import, export and +otherwise distribute the Licensed Materials as part of a Licensee Product, +provided that such Licensee Products include only embedded executable copies of +such Licensed Materials that execute solely and exclusively on TI Devices. + +b. Contractors. The licenses granted to you hereunder shall include your +on-site and off-site contractors (either an individual or entity), while such +contractors are performing work for or providing services to you, provided that +such contractors have executed work-for-hire agreements with you containing +applicable terms and conditions consistent with the terms and conditions set +forth in this Agreement and provided further that you shall be liable to TI for +any breach by your contractors of this Agreement to the same extent as you +would be if you had breached the Agreement yourself. + +c. No Other License. Nothing in this Agreement shall be construed as a license +to any intellectual property rights of TI other than those rights embodied in +the Licensed Materials provided to you by TI. EXCEPT AS PROVIDED HEREIN, NO +OTHER LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY OTHER TI +INTELLECTUAL PROPERTY RIGHTS IS GRANTED HEREIN. + +d. Covenant not to Sue. You agree not to assert a claim against TI or its +licensees that the Licensed Materials infringe your intellectual property +rights. + +e. Restrictions. You shall maintain the source code versions of the Licensed +Materials under password control protection and shall not disclose such source +code versions of the Licensed Materials, to any person other than your +employees and contractors whose job performance requires access. You shall not +use the Licensed Materials with a processing device other than a TI Device, and +you agree that any such unauthorized use of the Licensed Materials is a +material breach of this Agreement. You shall not use the Licensed Materials for +the purpose of analyzing or proving infringement of any of your patents by +either TI or TI's customers. Except as expressly provided in this Agreement, +you shall not copy, publish, disclose, display, provide, transfer or make +available the Licensed Materials to any third party and you shall not +sublicense, transfer, or assign the Licensed Materials or your rights under +this Agreement to any third party. You shall not mortgage, pledge or encumber +the Licensed Materials in any way. You may use the Licensed Materials with Open +Source Software or with software developed using Open Source Software tools +provided you do not incorporate, combine or distribute the Licensed Materials +in a manner that subjects the Licensed Materials to any license obligations or +any other intellectual property related terms of any license governing such +Open Source Software. + +f. Termination. This Agreement is effective on the date the Licensed Materials +are delivered to you together with this Agreement and will remain in full force +and effect until terminated. You may terminate this Agreement at any time by +written notice to TI. Without prejudice to any other rights, if you fail to +comply with the terms of this Agreement or you are acquired, TI may terminate +your right to use the Licensed Materials upon written notice to you. Upon +termination of this Agreement, you will destroy any and all copies of the +Licensed Materials in your possession, custody or control and provide to TI a +written statement signed by your authorized representative certifying such +destruction. Except for Sections 1(a), 1(b) and 1(d), all provisions of this +Agreement shall survive termination of this Agreement. + +2. Licensed Materials Ownership. The Licensed Materials are licensed, not sold +to you, and can only be used in accordance with the terms of this Agreement. +Subject to the licenses granted to you pursuant to this Agreement, TI and its +licensors own and shall continue to own all right, title and interest in and to +the Licensed Materials, including all copies thereof. You agree that all fixes, +modifications and improvements to the Licensed Materials conceived of or made +by TI that are based, either in whole or in part, on your feedback, suggestions +or recommendations are the exclusive property of TI and all right, title and +interest in and to such fixes, modifications or improvements to the Licensed +Materials will vest solely in TI. Moreover, you acknowledge and agree that when +your independently developed software or hardware components are combined, in +whole or in part, with the Licensed Materials, your right to use the combined +work that includes the Licensed Materials remains subject to the terms and +conditions of this Agreement. + +3. Intellectual Property Rights. + +a. The Licensed Materials contain copyrighted material, trade secrets and other +proprietary information of TI and its licensors and are protected by copyright +laws, international copyright treaties, and trade secret laws, as well as other +intellectual property laws. To protect TI's and its licensors' rights in the +Licensed Materials, you agree, except as specifically permitted by statute by a +provision that cannot be waived by contract, not to "unlock", decompile, +reverse engineer, disassemble or otherwise translate to a human-perceivable +form any portions of the Licensed Materials provided to you in object code +format only, nor permit any person or entity to do so. You shall not remove, +alter, cover, or obscure any confidentiality, trade secret, trade mark, patent, +copyright or other proprietary notice or other identifying marks or designs +from any component of the Licensed Materials and you shall reproduce and +include in all copies of the Licensed Materials the copyright notice(s) and +proprietary legend(s) of TI and its licensors as they appear in the Licensed +Materials. TI reserves all rights not specifically granted under this +Agreement. + +b. Certain Licensed Materials may be based on industry recognized standards or +software programs published by industry recognized standards bodies and certain +third parties may claim to own patents, copyrights, and other intellectual +property rights that cover implementation of those standards. You acknowledge +and agree that this Agreement does not convey a license to any such third party +patents, copyrights, and other intellectual property rights and that you are +solely responsible for any patent, copyright, or other intellectual property +right claim that relates to your use or distribution of the Licensed Materials +or your use or distribution of your products that include or incorporate the +Licensed Materials. Moreover, you acknowledge that you are responsible for any +fees or royalties that may be payable to any third party based on such third +party's interests in the Licensed Materials or any intellectual property rights +that cover implementation of any industry recognized standard, any software +program published by any industry recognized standards bodies or any other +proprietary technology. + +4. Audit Right. At TI's request, and within thirty (30) calendar days after +receiving written notice, you shall permit an internal or independent auditor +selected by TI to have access, no more than once each calendar year (unless the +immediately preceding audit revealed a discrepancy) and during your regular +business hours, to all of your equipment, records, and documents as may contain +information bearing upon the use of the Licensed Materials. You shall keep +full, complete, clear and accurate records with respect to product sales and +distributions for a period beginning with the then-current calendar year and +going back three (3) years. + +5. Confidential Information. You acknowledge and agree that the Licensed +Materials contain trade secrets and other confidential information of TI and +its licensors. You agree to use the Licensed Materials solely within the scope +of the licenses set forth herein, to maintain the Licensed Materials in strict +confidence, to use at least the same procedures and degree of care that you use +to prevent disclosure of your own confidential information of like importance +but in no instance less than reasonable care, and to prevent disclosure of the +Licensed Materials to any third party, except as may be necessary and required +in connection with your rights and obligations hereunder; provided, however, +that you may not provide the Licensed Materials to any business organization or +group within your company or to customers or contractors that design or +manufacture semiconductors unless TI gives written consent. You agree to obtain +executed confidentiality agreements with your employees and contractors having +access to the Licensed Materials and to diligently take steps to enforce such +agreements in this respect. TI may disclose your contact information to TI's +licensors. + +6. Warranties and Limitations. THE LICENSED MATERIALS ARE PROVIDED "AS IS". +FURTHERMORE, YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS HAVE NOT +BEEN TESTED OR CERTIFIED BY ANY GOVERNMENT AGENCY OR INDUSTRY REGULATORY +ORGANIZATION OR ANY OTHER THIRD PARTY ORGANIZATION.  YOU AGREE THAT PRIOR TO +USING, INCORPORATING OR DISTRIBUTING THE LICENSED MATERIALS IN OR WITH ANY +COMMERCIAL PRODUCT THAT YOU WILL THOROUGHLY TEST THE PRODUCT AND THE +FUNCTIONALITY OF THE LICENSED MATERIALS IN OR WITH THAT PRODUCT AND BE SOLELY +RESPONSIBLE FOR ANY PROBLEMS OR FAILURES. + +TI AND ITS LICENSORS MAKE NO WARRANTY OR REPRESENTATION, EITHER EXPRESS, +IMPLIED OR STATUTORY, REGARDING THE LICENSED MATERIALS, INCLUDING BUT NOT +LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A +PARTICULAR PURPOSE OR NON-INFRINGEMENT OF ANY THIRD PARTY PATENTS, COPYRIGHTS, +TRADE SECRETS OR OTHER INTELLECTUAL PROPERTY RIGHTS. YOU AGREE TO USE YOUR +INDEPENDENT JUDGMENT IN DEVELOPING YOUR PRODUCTS. NOTHING CONTAINED IN THIS +AGREEMENT WILL BE CONSTRUED AS A WARRANTY OR REPRESENTATION BY TI TO MAINTAIN +PRODUCTION OF ANY TI SEMICONDUCTOR DEVICE OR OTHER HARDWARE OR SOFTWARE WITH +WHICH THE LICENSED MATERIALS MAY BE USED. + +IN NO EVENT SHALL TI OR ITS LICENSORS, BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED, ON ANY THEORY OF +LIABILITY, IN CONNECTION WITH OR ARISING OUT OF THIS AGREEMENT OR THE USE OF +THE LICENSED MATERIALS REGARDLESS OF WHETHER TI HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, +COST OF REMOVAL OR REINSTALLATION, OUTSIDE COMPUTER TIME, LABOR COSTS, LOSS OF +DATA, LOSS OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF USE OR +INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S OR ITS LICENSORS' AGGREGATE +LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF YOUR USE OF THE LICENSED +MATERIALS EXCEED FIVE HUNDRED U.S. DOLLARS (US$500). + +Because some jurisdictions do not allow the exclusion or limitation of +incidental or consequential damages or limitation on how long an implied +warranty lasts, the above limitations or exclusions may not apply to you. + +7. Indemnification Disclaimer. YOU ACKNOWLEDGE AND AGREE THAT TI SHALL NOT BE +LIABLE FOR AND SHALL NOT DEFEND OR INDEMNIFY YOU AGAINST ANY THIRD PARTY +INFRINGEMENT CLAIM THAT RELATES TO OR IS BASED ON YOUR MANUFACTURE, USE, OR +DISTRIBUTION OF THE LICENSED MATERIALS OR YOUR MANUFACTURE, USE, OFFER FOR +SALE, SALE, IMPORTATION OR DISTRIBUTION OF YOUR PRODUCTS THAT INCLUDE OR +INCORPORATE THE LICENSED MATERIALS. + +You will defend and indemnify TI in the event of claim, liability or costs +(including reasonable attorney's fees related to Your use of the Licensed +Materials) relating in any way to Your violation of the terms of the License +Grants set forth in Section 1, or any other violation of other terms and +conditions of this Agreement. + +8. No Technical Support. TI and its licensors are under no obligation to +install, maintain or support the Licensed Materials. + +9. Notices. All notices to TI hereunder shall be delivered to Texas Instruments +Incorporated, 12500 TI Boulevard, Mail Station 8638, Dallas, Texas 75243, +Attention: Contracts Manager - Embedded Processing, with a copy to Texas +Instruments Incorporated, 13588 N. Central Expressway, Mail Station 3999, +Dallas, Texas 75243, Attention: Law Department - Embedded Processing. All +notices shall be deemed served when received by TI. + +10. Export Control. The Licensed Materials are subject to export control under +the U.S. Commerce Department's Export Administration Regulations ("EAR"). +Unless prior authorization is obtained from the U.S. Commerce Department, +neither you nor your subsidiaries shall export, re-export, or release, directly +or indirectly (including, without limitation, by permitting the Licensed +Materials to be downloaded), any technology, software, or software source code, +received from TI, or export, directly or indirectly, any direct product of such +technology, software, or software source code, to any person, destination or +country to which the export, re-export, or release of the technology, software, +or software source code, or direct product is prohibited by the EAR. You +represent and warrant that you (i) are not located in, or under the control of, +a national or resident of Cuba, Iran, North Korea, Sudan and Syria or any other +country subject to a U.S. goods embargo; (ii) are not on the U.S. Treasury +Department's List of Specially Designated Nationals or the U.S. Commerce +Department's Denied Persons List or Entity List; and (iii) will not use the +Licensed Materials or transfer the Licensed Materials for use in any military, +nuclear, chemical or biological weapons, or missile technology end-uses. Any +software export classification made by TI shall not be construed as a +representation or warranty regarding the proper export classification for such +software or whether an export license or other documentation is required for +the exportation of such software. + +11. Governing Law and Severability; Waiver. This Agreement will be governed by +and interpreted in accordance with the laws of the State of Texas, without +reference to conflict of laws principles. If for any reason a court of +competent jurisdiction finds any provision of the Agreement to be +unenforceable, that provision will be enforced to the maximum extent possible +to effectuate the intent of the parties, and the remainder of the Agreement +shall continue in full force and effect. This Agreement shall not be governed +by the United Nations Convention on Contracts for the International Sale of +Goods, or by the Uniform Computer Information Transactions Act (UCITA). The +parties agree that non-exclusive jurisdiction for any dispute arising out of or +relating to this Agreement lies within the courts located in the State of +Texas. Notwithstanding the foregoing, any judgment may be enforced in any +United States or foreign court, and either party may seek injunctive relief in +any United States or foreign court. Failure by TI to enforce any provision of +this Agreement shall not be deemed a waiver of future enforcement of that or +any other provision in this Agreement or any other agreement that may be in +place between the parties. + +12. PRC Provisions. If you are located in the People's Republic of China +("PRC") or if the Licensed Materials will be sent to the PRC, the following +provisions shall apply: + +a. Registration Requirements. You shall be solely responsible for performing +all acts and obtaining all approvals that may be required in connection with +this Agreement by the government of the PRC, including but not limited to +registering pursuant to, and otherwise complying with, the PRC Measures on the +Administration of Software Products, Management Regulations on Technology +Import-Export, and Technology Import and Export Contract Registration +Management Rules. Upon receipt of such approvals from the government +authorities, you shall forward evidence of all such approvals to TI for its +records. In the event that you fail to obtain any such approval or +registration, you shall be solely responsible for any and all losses, damages +or costs resulting therefrom, and shall indemnify TI for all such losses, +damages or costs. + +b. Governing Language. This Agreement is written and executed in the English +language and shall be authoritative and controlling, whether or not translated +into a language other than English to comply with law or for reference +purposes. If a translation of this Agreement is required for any purpose, +including but not limited to registration of the Agreement pursuant to any +governmental laws, regulations or rules, you shall be solely responsible for +creating such translation. + +13. Contingencies. TI shall not be in breach of this Agreement and shall not be +liable for any non-performance or delay in performance if such non-performance +or delay is due to a force majeure event or other circumstances beyond TI's +reasonable control. + +14. Entire Agreement. This is the entire agreement between you and TI and this +Agreement supersedes any prior agreement between the parties related to the +subject matter of this Agreement. Notwithstanding the foregoing, any signed and +effective software license agreement relating to the subject matter hereof and +stating expressly that such agreement shall control regardless of any +subsequent click-wrap, shrink-wrap or web-wrap, shall supersede the terms of +this Agreement. No amendment or modification of this Agreement will be +effective unless in writing and signed by a duly authorized representative of +TI. You hereby warrant and represent that you have obtained all authorizations +and other applicable consents required empowering you to enter into this +Agreement. + diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathCPP.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathCPP.h new file mode 100644 index 0000000000000000000000000000000000000000..692f98ef9d75aa6906843c4e65108891e57f81ba --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathCPP.h @@ -0,0 +1,15317 @@ +//***************************************************************************** +// +// IQmathCPP.h - IQmath library C++ language function definitions. +// +// Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva IQmath Library. +// +//***************************************************************************** + +#ifndef __IQMATHCPP_H__ +#define __IQMATHCPP_H__ + +//***************************************************************************** +// +// Include some standard headers, as required based on the math type. +// +//***************************************************************************** +#include +#if MATH_TYPE == FLOAT_MATH +#include +#include +#endif + +//***************************************************************************** +// +// See if IQmath or floating point is being used. +// +//***************************************************************************** +#if MATH_TYPE == IQ_MATH + +//***************************************************************************** +// +// The C++ class for the various IQ formats. +// +//***************************************************************************** +struct iq +{ + // + // Constructors. + // + iq() : val(0) + { + } + + iq(_iq A) : val(A) + { + } + + // + // Copy constructor. + // + iq(const iq &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq &operator=(const iq &A); + + // + // Arithmetic operators. + // + inline iq &operator+=(const iq &A); + inline iq &operator-=(const iq &A); + inline iq &operator*=(const iq &A); + inline iq &operator/=(const iq &A); + + // + // Bitwise operators. + // + inline iq &operator&=(const _iq &A); + inline iq &operator|=(const _iq &A); + inline iq &operator^=(const _iq &A); + + // + // The IQ number. + // + _iq val; +}; + +struct iq30 +{ + // + // Constructors. + // + iq30() : val(0) + { + } + + iq30(_iq30 A) : val(A) + { + } + + // + // Copy constructor. + // + iq30(const iq30 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq30 &operator=(const iq30 &A); + + // + // Arithmetic operators. + // + inline iq30 &operator+=(const iq30 &A); + inline iq30 &operator-=(const iq30 &A); + inline iq30 &operator*=(const iq30 &A); + inline iq30 &operator/=(const iq30 &A); + + // + // Bitwise operators. + // + inline iq30 &operator&=(const _iq30 &A); + inline iq30 &operator|=(const _iq30 &A); + inline iq30 &operator^=(const _iq30 &A); + + // + // The IQ number. + // + _iq30 val; +}; + +struct iq29 +{ + // + // Constructors. + // + iq29() : val(0) + { + } + + iq29(_iq29 A) : val(A) + { + } + + // + // Copy constructor. + // + iq29(const iq29 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq29 &operator=(const iq29 &A); + + // + // Arithmetic operators. + // + inline iq29 &operator+=(const iq29 &A); + inline iq29 &operator-=(const iq29 &A); + inline iq29 &operator*=(const iq29 &A); + inline iq29 &operator/=(const iq29 &A); + + // + // Bitwise operators. + // + inline iq29 &operator&=(const _iq29 &A); + inline iq29 &operator|=(const _iq29 &A); + inline iq29 &operator^=(const _iq29 &A); + + // + // The IQ number. + // + _iq29 val; +}; + +struct iq28 +{ + // + // Constructors. + // + iq28() : val(0) + { + } + + iq28(_iq28 A) : val(A) + { + } + + // + // Copy constructor. + // + iq28(const iq28 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq28 &operator=(const iq28 &A); + + // + // Arithmetic operators. + // + inline iq28 &operator+=(const iq28 &A); + inline iq28 &operator-=(const iq28 &A); + inline iq28 &operator*=(const iq28 &A); + inline iq28 &operator/=(const iq28 &A); + + // + // Bitwise operators. + // + inline iq28 &operator&=(const _iq28 &A); + inline iq28 &operator|=(const _iq28 &A); + inline iq28 &operator^=(const _iq28 &A); + + // + // The IQ number. + // + _iq28 val; +}; + +struct iq27 +{ + // + // Constructors. + // + iq27() : val(0) + { + } + + iq27(_iq27 A) : val(A) + { + } + + // + // Copy constructor. + // + iq27(const iq27 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq27 &operator=(const iq27 &A); + + // + // Arithmetic operators. + // + inline iq27 &operator+=(const iq27 &A); + inline iq27 &operator-=(const iq27 &A); + inline iq27 &operator*=(const iq27 &A); + inline iq27 &operator/=(const iq27 &A); + + // + // Bitwise operators. + // + inline iq27 &operator&=(const _iq27 &A); + inline iq27 &operator|=(const _iq27 &A); + inline iq27 &operator^=(const _iq27 &A); + + // + // The IQ number. + // + _iq27 val; +}; + +struct iq26 +{ + // + // Constructors. + // + iq26() : val(0) + { + } + + iq26(_iq26 A) : val(A) + { + } + + // + // Copy constructor. + // + iq26(const iq26 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq26 &operator=(const iq26 &A); + + // + // Arithmetic operators. + // + inline iq26 &operator+=(const iq26 &A); + inline iq26 &operator-=(const iq26 &A); + inline iq26 &operator*=(const iq26 &A); + inline iq26 &operator/=(const iq26 &A); + + // + // Bitwise operators. + // + inline iq26 &operator&=(const _iq26 &A); + inline iq26 &operator|=(const _iq26 &A); + inline iq26 &operator^=(const _iq26 &A); + + // + // The IQ number. + // + _iq26 val; +}; + +struct iq25 +{ + // + // Constructors. + // + iq25() : val(0) + { + } + + iq25(_iq25 A) : val(A) + { + } + + // + // Copy constructor. + // + iq25(const iq25 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq25 &operator=(const iq25 &A); + + // + // Arithmetic operators. + // + inline iq25 &operator+=(const iq25 &A); + inline iq25 &operator-=(const iq25 &A); + inline iq25 &operator*=(const iq25 &A); + inline iq25 &operator/=(const iq25 &A); + + // + // Bitwise operators. + // + inline iq25 &operator&=(const _iq25 &A); + inline iq25 &operator|=(const _iq25 &A); + inline iq25 &operator^=(const _iq25 &A); + + // + // The IQ number. + // + _iq25 val; +}; + +struct iq24 +{ + // + // Constructors. + // + iq24() : val(0) + { + } + + iq24(_iq24 A) : val(A) + { + } + + // + // Copy constructor. + // + iq24(const iq24 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq24 &operator=(const iq24 &A); + + // + // Arithmetic operators. + // + inline iq24 &operator+=(const iq24 &A); + inline iq24 &operator-=(const iq24 &A); + inline iq24 &operator*=(const iq24 &A); + inline iq24 &operator/=(const iq24 &A); + + // + // Bitwise operators. + // + inline iq24 &operator&=(const _iq24 &A); + inline iq24 &operator|=(const _iq24 &A); + inline iq24 &operator^=(const _iq24 &A); + + // + // The IQ number. + // + _iq24 val; +}; + +struct iq23 +{ + // + // Constructors. + // + iq23() : val(0) + { + } + + iq23(_iq23 A) : val(A) + { + } + + // + // Copy constructor. + // + iq23(const iq23 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq23 &operator=(const iq23 &A); + + // + // Arithmetic operators. + // + inline iq23 &operator+=(const iq23 &A); + inline iq23 &operator-=(const iq23 &A); + inline iq23 &operator*=(const iq23 &A); + inline iq23 &operator/=(const iq23 &A); + + // + // Bitwise operators. + // + inline iq23 &operator&=(const _iq23 &A); + inline iq23 &operator|=(const _iq23 &A); + inline iq23 &operator^=(const _iq23 &A); + + // + // The IQ number. + // + _iq23 val; +}; + +struct iq22 +{ + // + // Constructors. + // + iq22() : val(0) + { + } + + iq22(_iq22 A) : val(A) + { + } + + // + // Copy constructor. + // + iq22(const iq22 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq22 &operator=(const iq22 &A); + + // + // Arithmetic operators. + // + inline iq22 &operator+=(const iq22 &A); + inline iq22 &operator-=(const iq22 &A); + inline iq22 &operator*=(const iq22 &A); + inline iq22 &operator/=(const iq22 &A); + + // + // Bitwise operators. + // + inline iq22 &operator&=(const _iq22 &A); + inline iq22 &operator|=(const _iq22 &A); + inline iq22 &operator^=(const _iq22 &A); + + // + // The IQ number. + // + _iq22 val; +}; + +struct iq21 +{ + // + // Constructors. + // + iq21() : val(0) + { + } + + iq21(_iq21 A) : val(A) + { + } + + // + // Copy constructor. + // + iq21(const iq21 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq21 &operator=(const iq21 &A); + + // + // Arithmetic operators. + // + inline iq21 &operator+=(const iq21 &A); + inline iq21 &operator-=(const iq21 &A); + inline iq21 &operator*=(const iq21 &A); + inline iq21 &operator/=(const iq21 &A); + + // + // Bitwise operators. + // + inline iq21 &operator&=(const _iq21 &A); + inline iq21 &operator|=(const _iq21 &A); + inline iq21 &operator^=(const _iq21 &A); + + // + // The IQ number. + // + _iq21 val; +}; + +struct iq20 +{ + // + // Constructors. + // + iq20() : val(0) + { + } + + iq20(_iq20 A) : val(A) + { + } + + // + // Copy constructor. + // + iq20(const iq20 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq20 &operator=(const iq20 &A); + + // + // Arithmetic operators. + // + inline iq20 &operator+=(const iq20 &A); + inline iq20 &operator-=(const iq20 &A); + inline iq20 &operator*=(const iq20 &A); + inline iq20 &operator/=(const iq20 &A); + + // + // Bitwise operators. + // + inline iq20 &operator&=(const _iq20 &A); + inline iq20 &operator|=(const _iq20 &A); + inline iq20 &operator^=(const _iq20 &A); + + // + // The IQ number. + // + _iq20 val; +}; + +struct iq19 +{ + // + // Constructors. + // + iq19() : val(0) + { + } + + iq19(_iq19 A) : val(A) + { + } + + // + // Copy constructor. + // + iq19(const iq19 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq19 &operator=(const iq19 &A); + + // + // Arithmetic operators. + // + inline iq19 &operator+=(const iq19 &A); + inline iq19 &operator-=(const iq19 &A); + inline iq19 &operator*=(const iq19 &A); + inline iq19 &operator/=(const iq19 &A); + + // + // Bitwise operators. + // + inline iq19 &operator&=(const _iq19 &A); + inline iq19 &operator|=(const _iq19 &A); + inline iq19 &operator^=(const _iq19 &A); + + // + // The IQ number. + // + _iq19 val; +}; + +struct iq18 +{ + // + // Constructors. + // + iq18() : val(0) + { + } + + iq18(_iq18 A) : val(A) + { + } + + // + // Copy constructor. + // + iq18(const iq18 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq18 &operator=(const iq18 &A); + + // + // Arithmetic operators. + // + inline iq18 &operator+=(const iq18 &A); + inline iq18 &operator-=(const iq18 &A); + inline iq18 &operator*=(const iq18 &A); + inline iq18 &operator/=(const iq18 &A); + + // + // Bitwise operators. + // + inline iq18 &operator&=(const _iq18 &A); + inline iq18 &operator|=(const _iq18 &A); + inline iq18 &operator^=(const _iq18 &A); + + // + // The IQ number. + // + _iq18 val; +}; + +struct iq17 +{ + // + // Constructors. + // + iq17() : val(0) + { + } + + iq17(_iq17 A) : val(A) + { + } + + // + // Copy constructor. + // + iq17(const iq17 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq17 &operator=(const iq17 &A); + + // + // Arithmetic operators. + // + inline iq17 &operator+=(const iq17 &A); + inline iq17 &operator-=(const iq17 &A); + inline iq17 &operator*=(const iq17 &A); + inline iq17 &operator/=(const iq17 &A); + + // + // Bitwise operators. + // + inline iq17 &operator&=(const _iq17 &A); + inline iq17 &operator|=(const _iq17 &A); + inline iq17 &operator^=(const _iq17 &A); + + // + // The IQ number. + // + _iq17 val; +}; + +struct iq16 +{ + // + // Constructors. + // + iq16() : val(0) + { + } + + iq16(_iq16 A) : val(A) + { + } + + // + // Copy constructor. + // + iq16(const iq16 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq16 &operator=(const iq16 &A); + + // + // Arithmetic operators. + // + inline iq16 &operator+=(const iq16 &A); + inline iq16 &operator-=(const iq16 &A); + inline iq16 &operator*=(const iq16 &A); + inline iq16 &operator/=(const iq16 &A); + + // + // Bitwise operators. + // + inline iq16 &operator&=(const _iq16 &A); + inline iq16 &operator|=(const _iq16 &A); + inline iq16 &operator^=(const _iq16 &A); + + // + // The IQ number. + // + _iq16 val; +}; + +struct iq15 +{ + // + // Constructors. + // + iq15() : val(0) + { + } + + iq15(_iq15 A) : val(A) + { + } + + // + // Copy constructor. + // + iq15(const iq15 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq15 &operator=(const iq15 &A); + + // + // Arithmetic operators. + // + inline iq15 &operator+=(const iq15 &A); + inline iq15 &operator-=(const iq15 &A); + inline iq15 &operator*=(const iq15 &A); + inline iq15 &operator/=(const iq15 &A); + + // + // Bitwise operators. + // + inline iq15 &operator&=(const _iq15 &A); + inline iq15 &operator|=(const _iq15 &A); + inline iq15 &operator^=(const _iq15 &A); + + // + // The IQ number. + // + _iq15 val; +}; + +struct iq14 +{ + // + // Constructors. + // + iq14() : val(0) + { + } + + iq14(_iq14 A) : val(A) + { + } + + // + // Copy constructor. + // + iq14(const iq14 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq14 &operator=(const iq14 &A); + + // + // Arithmetic operators. + // + inline iq14 &operator+=(const iq14 &A); + inline iq14 &operator-=(const iq14 &A); + inline iq14 &operator*=(const iq14 &A); + inline iq14 &operator/=(const iq14 &A); + + // + // Bitwise operators. + // + inline iq14 &operator&=(const _iq14 &A); + inline iq14 &operator|=(const _iq14 &A); + inline iq14 &operator^=(const _iq14 &A); + + // + // The IQ number. + // + _iq14 val; +}; + +struct iq13 +{ + // + // Constructors. + // + iq13() : val(0) + { + } + + iq13(_iq13 A) : val(A) + { + } + + // + // Copy constructor. + // + iq13(const iq13 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq13 &operator=(const iq13 &A); + + // + // Arithmetic operators. + // + inline iq13 &operator+=(const iq13 &A); + inline iq13 &operator-=(const iq13 &A); + inline iq13 &operator*=(const iq13 &A); + inline iq13 &operator/=(const iq13 &A); + + // + // Bitwise operators. + // + inline iq13 &operator&=(const _iq13 &A); + inline iq13 &operator|=(const _iq13 &A); + inline iq13 &operator^=(const _iq13 &A); + + // + // The IQ number. + // + _iq13 val; +}; + +struct iq12 +{ + // + // Constructors. + // + iq12() : val(0) + { + } + + iq12(_iq12 A) : val(A) + { + } + + // + // Copy constructor. + // + iq12(const iq12 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq12 &operator=(const iq12 &A); + + // + // Arithmetic operators. + // + inline iq12 &operator+=(const iq12 &A); + inline iq12 &operator-=(const iq12 &A); + inline iq12 &operator*=(const iq12 &A); + inline iq12 &operator/=(const iq12 &A); + + // + // Bitwise operators. + // + inline iq12 &operator&=(const _iq12 &A); + inline iq12 &operator|=(const _iq12 &A); + inline iq12 &operator^=(const _iq12 &A); + + // + // The IQ number. + // + _iq12 val; +}; + +struct iq11 +{ + // + // Constructors. + // + iq11() : val(0) + { + } + + iq11(_iq11 A) : val(A) + { + } + + // + // Copy constructor. + // + iq11(const iq11 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq11 &operator=(const iq11 &A); + + // + // Arithmetic operators. + // + inline iq11 &operator+=(const iq11 &A); + inline iq11 &operator-=(const iq11 &A); + inline iq11 &operator*=(const iq11 &A); + inline iq11 &operator/=(const iq11 &A); + + // + // Bitwise operators. + // + inline iq11 &operator&=(const _iq11 &A); + inline iq11 &operator|=(const _iq11 &A); + inline iq11 &operator^=(const _iq11 &A); + + // + // The IQ number. + // + _iq11 val; +}; + +struct iq10 +{ + // + // Constructors. + // + iq10() : val(0) + { + } + + iq10(_iq10 A) : val(A) + { + } + + // + // Copy constructor. + // + iq10(const iq10 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq10 &operator=(const iq10 &A); + + // + // Arithmetic operators. + // + inline iq10 &operator+=(const iq10 &A); + inline iq10 &operator-=(const iq10 &A); + inline iq10 &operator*=(const iq10 &A); + inline iq10 &operator/=(const iq10 &A); + + // + // Bitwise operators. + // + inline iq10 &operator&=(const _iq10 &A); + inline iq10 &operator|=(const _iq10 &A); + inline iq10 &operator^=(const _iq10 &A); + + // + // The IQ number. + // + _iq10 val; +}; + +struct iq9 +{ + // + // Constructors. + // + iq9() : val(0) + { + } + + iq9(_iq9 A) : val(A) + { + } + + // + // Copy constructor. + // + iq9(const iq9 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq9 &operator=(const iq9 &A); + + // + // Arithmetic operators. + // + inline iq9 &operator+=(const iq9 &A); + inline iq9 &operator-=(const iq9 &A); + inline iq9 &operator*=(const iq9 &A); + inline iq9 &operator/=(const iq9 &A); + + // + // Bitwise operators. + // + inline iq9 &operator&=(const _iq9 &A); + inline iq9 &operator|=(const _iq9 &A); + inline iq9 &operator^=(const _iq9 &A); + + // + // The IQ number. + // + _iq9 val; +}; + +struct iq8 +{ + // + // Constructors. + // + iq8() : val(0) + { + } + + iq8(_iq8 A) : val(A) + { + } + + // + // Copy constructor. + // + iq8(const iq8 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq8 &operator=(const iq8 &A); + + // + // Arithmetic operators. + // + inline iq8 &operator+=(const iq8 &A); + inline iq8 &operator-=(const iq8 &A); + inline iq8 &operator*=(const iq8 &A); + inline iq8 &operator/=(const iq8 &A); + + // + // Bitwise operators. + // + inline iq8 &operator&=(const _iq8 &A); + inline iq8 &operator|=(const _iq8 &A); + inline iq8 &operator^=(const _iq8 &A); + + // + // The IQ number. + // + _iq8 val; +}; + +struct iq7 +{ + // + // Constructors. + // + iq7() : val(0) + { + } + + iq7(_iq7 A) : val(A) + { + } + + // + // Copy constructor. + // + iq7(const iq7 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq7 &operator=(const iq7 &A); + + // + // Arithmetic operators. + // + inline iq7 &operator+=(const iq7 &A); + inline iq7 &operator-=(const iq7 &A); + inline iq7 &operator*=(const iq7 &A); + inline iq7 &operator/=(const iq7 &A); + + // + // Bitwise operators. + // + inline iq7 &operator&=(const _iq7 &A); + inline iq7 &operator|=(const _iq7 &A); + inline iq7 &operator^=(const _iq7 &A); + + // + // The IQ number. + // + _iq7 val; +}; + +struct iq6 +{ + // + // Constructors. + // + iq6() : val(0) + { + } + + iq6(_iq6 A) : val(A) + { + } + + // + // Copy constructor. + // + iq6(const iq6 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq6 &operator=(const iq6 &A); + + // + // Arithmetic operators. + // + inline iq6 &operator+=(const iq6 &A); + inline iq6 &operator-=(const iq6 &A); + inline iq6 &operator*=(const iq6 &A); + inline iq6 &operator/=(const iq6 &A); + + // + // Bitwise operators. + // + inline iq6 &operator&=(const _iq6 &A); + inline iq6 &operator|=(const _iq6 &A); + inline iq6 &operator^=(const _iq6 &A); + + // + // The IQ number. + // + _iq6 val; +}; + +struct iq5 +{ + // + // Constructors. + // + iq5() : val(0) + { + } + + iq5(_iq5 A) : val(A) + { + } + + // + // Copy constructor. + // + iq5(const iq5 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq5 &operator=(const iq5 &A); + + // + // Arithmetic operators. + // + inline iq5 &operator+=(const iq5 &A); + inline iq5 &operator-=(const iq5 &A); + inline iq5 &operator*=(const iq5 &A); + inline iq5 &operator/=(const iq5 &A); + + // + // Bitwise operators. + // + inline iq5 &operator&=(const _iq5 &A); + inline iq5 &operator|=(const _iq5 &A); + inline iq5 &operator^=(const _iq5 &A); + + // + // The IQ number. + // + _iq5 val; +}; + +struct iq4 +{ + // + // Constructors. + // + iq4() : val(0) + { + } + + iq4(_iq4 A) : val(A) + { + } + + // + // Copy constructor. + // + iq4(const iq4 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq4 &operator=(const iq4 &A); + + // + // Arithmetic operators. + // + inline iq4 &operator+=(const iq4 &A); + inline iq4 &operator-=(const iq4 &A); + inline iq4 &operator*=(const iq4 &A); + inline iq4 &operator/=(const iq4 &A); + + // + // Bitwise operators. + // + inline iq4 &operator&=(const _iq4 &A); + inline iq4 &operator|=(const _iq4 &A); + inline iq4 &operator^=(const _iq4 &A); + + // + // The IQ number. + // + _iq4 val; +}; + +struct iq3 +{ + // + // Constructors. + // + iq3() : val(0) + { + } + + iq3(_iq3 A) : val(A) + { + } + + // + // Copy constructor. + // + iq3(const iq3 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq3 &operator=(const iq3 &A); + + // + // Arithmetic operators. + // + inline iq3 &operator+=(const iq3 &A); + inline iq3 &operator-=(const iq3 &A); + inline iq3 &operator*=(const iq3 &A); + inline iq3 &operator/=(const iq3 &A); + + // + // Bitwise operators. + // + inline iq3 &operator&=(const _iq3 &A); + inline iq3 &operator|=(const _iq3 &A); + inline iq3 &operator^=(const _iq3 &A); + + // + // The IQ number. + // + _iq3 val; +}; + +struct iq2 +{ + // + // Constructors. + // + iq2() : val(0) + { + } + + iq2(_iq2 A) : val(A) + { + } + + // + // Copy constructor. + // + iq2(const iq2 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq2 &operator=(const iq2 &A); + + // + // Arithmetic operators. + // + inline iq2 &operator+=(const iq2 &A); + inline iq2 &operator-=(const iq2 &A); + inline iq2 &operator*=(const iq2 &A); + inline iq2 &operator/=(const iq2 &A); + + // + // Bitwise operators. + // + inline iq2 &operator&=(const _iq2 &A); + inline iq2 &operator|=(const _iq2 &A); + inline iq2 &operator^=(const _iq2 &A); + + // + // The IQ number. + // + _iq2 val; +}; + +struct iq1 +{ + // + // Constructors. + // + iq1() : val(0) + { + } + + iq1(_iq1 A) : val(A) + { + } + + // + // Copy constructor. + // + iq1(const iq1 &A) : val(A.val) + { + } + + // + // Assignment operator. + // + inline iq1 &operator=(const iq1 &A); + + // + // Arithmetic operators. + // + inline iq1 &operator+=(const iq1 &A); + inline iq1 &operator-=(const iq1 &A); + inline iq1 &operator*=(const iq1 &A); + inline iq1 &operator/=(const iq1 &A); + + // + // Bitwise operators. + // + inline iq1 &operator&=(const _iq1 &A); + inline iq1 &operator|=(const _iq1 &A); + inline iq1 &operator^=(const _iq1 &A); + + // + // The IQ number. + // + _iq1 val; +}; + +//***************************************************************************** +// +// Convert a value into a IQ number. +// +//***************************************************************************** +#define IQ30(A) (iq30)_IQ30(A) +#define IQ29(A) (iq29)_IQ29(A) +#define IQ28(A) (iq28)_IQ28(A) +#define IQ27(A) (iq27)_IQ27(A) +#define IQ26(A) (iq26)_IQ26(A) +#define IQ25(A) (iq25)_IQ25(A) +#define IQ24(A) (iq24)_IQ24(A) +#define IQ23(A) (iq23)_IQ23(A) +#define IQ22(A) (iq22)_IQ22(A) +#define IQ21(A) (iq21)_IQ21(A) +#define IQ20(A) (iq20)_IQ20(A) +#define IQ19(A) (iq19)_IQ19(A) +#define IQ18(A) (iq18)_IQ18(A) +#define IQ17(A) (iq17)_IQ17(A) +#define IQ16(A) (iq16)_IQ16(A) +#define IQ15(A) (iq15)_IQ15(A) +#define IQ14(A) (iq14)_IQ14(A) +#define IQ13(A) (iq13)_IQ13(A) +#define IQ12(A) (iq12)_IQ12(A) +#define IQ11(A) (iq11)_IQ11(A) +#define IQ10(A) (iq10)_IQ10(A) +#define IQ9(A) (iq9)_IQ9(A) +#define IQ8(A) (iq8)_IQ8(A) +#define IQ7(A) (iq7)_IQ7(A) +#define IQ6(A) (iq6)_IQ6(A) +#define IQ5(A) (iq5)_IQ5(A) +#define IQ4(A) (iq4)_IQ4(A) +#define IQ3(A) (iq3)_IQ3(A) +#define IQ2(A) (iq2)_IQ2(A) +#define IQ1(A) (iq1)_IQ1(A) +#define IQ(A) (iq)_IQ(A) + +//***************************************************************************** +// +// Convert a IQ number to a floating point value. +// +//***************************************************************************** +inline float IQ30toF(const iq30 &A) { return(_IQ30toF(A.val)); } +inline float IQ29toF(const iq29 &A) { return(_IQ29toF(A.val)); } +inline float IQ28toF(const iq28 &A) { return(_IQ28toF(A.val)); } +inline float IQ27toF(const iq27 &A) { return(_IQ27toF(A.val)); } +inline float IQ26toF(const iq26 &A) { return(_IQ26toF(A.val)); } +inline float IQ25toF(const iq25 &A) { return(_IQ25toF(A.val)); } +inline float IQ24toF(const iq24 &A) { return(_IQ24toF(A.val)); } +inline float IQ23toF(const iq23 &A) { return(_IQ23toF(A.val)); } +inline float IQ22toF(const iq22 &A) { return(_IQ22toF(A.val)); } +inline float IQ21toF(const iq21 &A) { return(_IQ21toF(A.val)); } +inline float IQ20toF(const iq20 &A) { return(_IQ20toF(A.val)); } +inline float IQ19toF(const iq19 &A) { return(_IQ19toF(A.val)); } +inline float IQ18toF(const iq18 &A) { return(_IQ18toF(A.val)); } +inline float IQ17toF(const iq17 &A) { return(_IQ17toF(A.val)); } +inline float IQ16toF(const iq16 &A) { return(_IQ16toF(A.val)); } +inline float IQ15toF(const iq15 &A) { return(_IQ15toF(A.val)); } +inline float IQ14toF(const iq14 &A) { return(_IQ14toF(A.val)); } +inline float IQ13toF(const iq13 &A) { return(_IQ13toF(A.val)); } +inline float IQ12toF(const iq12 &A) { return(_IQ12toF(A.val)); } +inline float IQ11toF(const iq11 &A) { return(_IQ11toF(A.val)); } +inline float IQ10toF(const iq10 &A) { return(_IQ10toF(A.val)); } +inline float IQ9toF(const iq9 &A) { return(_IQ9toF(A.val)); } +inline float IQ8toF(const iq8 &A) { return(_IQ8toF(A.val)); } +inline float IQ7toF(const iq7 &A) { return(_IQ7toF(A.val)); } +inline float IQ6toF(const iq6 &A) { return(_IQ6toF(A.val)); } +inline float IQ5toF(const iq5 &A) { return(_IQ5toF(A.val)); } +inline float IQ4toF(const iq4 &A) { return(_IQ4toF(A.val)); } +inline float IQ3toF(const iq3 &A) { return(_IQ3toF(A.val)); } +inline float IQ2toF(const iq2 &A) { return(_IQ2toF(A.val)); } +inline float IQ1toF(const iq1 &A) { return(_IQ1toF(A.val)); } +inline float IQtoF(const iq &A) { return(_IQtoF(A.val)); } + +//***************************************************************************** +// +// Convert an IQ number to a double-precision floating point value. +// +//***************************************************************************** +inline double IQ30toD(const iq30 &A) { return(_IQ30toD(A.val)); } +inline double IQ29toD(const iq29 &A) { return(_IQ29toD(A.val)); } +inline double IQ28toD(const iq28 &A) { return(_IQ28toD(A.val)); } +inline double IQ27toD(const iq27 &A) { return(_IQ27toD(A.val)); } +inline double IQ26toD(const iq26 &A) { return(_IQ26toD(A.val)); } +inline double IQ25toD(const iq25 &A) { return(_IQ25toD(A.val)); } +inline double IQ24toD(const iq24 &A) { return(_IQ24toD(A.val)); } +inline double IQ23toD(const iq23 &A) { return(_IQ23toD(A.val)); } +inline double IQ22toD(const iq22 &A) { return(_IQ22toD(A.val)); } +inline double IQ21toD(const iq21 &A) { return(_IQ21toD(A.val)); } +inline double IQ20toD(const iq20 &A) { return(_IQ20toD(A.val)); } +inline double IQ19toD(const iq19 &A) { return(_IQ19toD(A.val)); } +inline double IQ18toD(const iq18 &A) { return(_IQ18toD(A.val)); } +inline double IQ17toD(const iq17 &A) { return(_IQ17toD(A.val)); } +inline double IQ16toD(const iq16 &A) { return(_IQ16toD(A.val)); } +inline double IQ15toD(const iq15 &A) { return(_IQ15toD(A.val)); } +inline double IQ14toD(const iq14 &A) { return(_IQ14toD(A.val)); } +inline double IQ13toD(const iq13 &A) { return(_IQ13toD(A.val)); } +inline double IQ12toD(const iq12 &A) { return(_IQ12toD(A.val)); } +inline double IQ11toD(const iq11 &A) { return(_IQ11toD(A.val)); } +inline double IQ10toD(const iq10 &A) { return(_IQ10toD(A.val)); } +inline double IQ9toD(const iq9 &A) { return(_IQ9toD(A.val)); } +inline double IQ8toD(const iq8 &A) { return(_IQ8toD(A.val)); } +inline double IQ7toD(const iq7 &A) { return(_IQ7toD(A.val)); } +inline double IQ6toD(const iq6 &A) { return(_IQ6toD(A.val)); } +inline double IQ5toD(const iq5 &A) { return(_IQ5toD(A.val)); } +inline double IQ4toD(const iq4 &A) { return(_IQ4toD(A.val)); } +inline double IQ3toD(const iq3 &A) { return(_IQ3toD(A.val)); } +inline double IQ2toD(const iq2 &A) { return(_IQ2toD(A.val)); } +inline double IQ1toD(const iq1 &A) { return(_IQ1toD(A.val)); } +inline double IQtoD(const iq &A) { return(_IQtoD(A.val)); } + +//***************************************************************************** +// +// Saturates an IQ number in a given range. +// +//***************************************************************************** +inline iq30 +IQsat(const iq30 &A, const iq30 &Pos, const iq30 &Neg) +{ + iq30 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq29 +IQsat(const iq29 &A, const iq29 &Pos, const iq29 &Neg) +{ + iq29 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq28 +IQsat(const iq28 &A, const iq28 &Pos, const iq28 &Neg) +{ + iq28 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq27 +IQsat(const iq27 &A, const iq27 &Pos, const iq27 &Neg) +{ + iq27 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq26 +IQsat(const iq26 &A, const iq26 &Pos, const iq26 &Neg) +{ + iq26 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq25 +IQsat(const iq25 &A, const iq25 &Pos, const iq25 &Neg) +{ + iq25 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq24 +IQsat(const iq24 &A, const iq24 &Pos, const iq24 &Neg) +{ + iq24 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq23 +IQsat(const iq23 &A, const iq23 &Pos, const iq23 &Neg) +{ + iq23 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq22 +IQsat(const iq22 &A, const iq22 &Pos, const iq22 &Neg) +{ + iq22 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq21 +IQsat(const iq21 &A, const iq21 &Pos, const iq21 &Neg) +{ + iq21 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq20 +IQsat(const iq20 &A, const iq20 &Pos, const iq20 &Neg) +{ + iq20 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq19 +IQsat(const iq19 &A, const iq19 &Pos, const iq19 &Neg) +{ + iq19 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq18 +IQsat(const iq18 &A, const iq18 &Pos, const iq18 &Neg) +{ + iq18 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq17 +IQsat(const iq17 &A, const iq17 &Pos, const iq17 &Neg) +{ + iq17 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq16 +IQsat(const iq16 &A, const iq16 &Pos, const iq16 &Neg) +{ + iq16 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq15 +IQsat(const iq15 &A, const iq15 &Pos, const iq15 &Neg) +{ + iq15 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq14 +IQsat(const iq14 &A, const iq14 &Pos, const iq14 &Neg) +{ + iq14 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq13 +IQsat(const iq13 &A, const iq13 &Pos, const iq13 &Neg) +{ + iq13 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq12 +IQsat(const iq12 &A, const iq12 &Pos, const iq12 &Neg) +{ + iq12 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq11 +IQsat(const iq11 &A, const iq11 &Pos, const iq11 &Neg) +{ + iq11 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq10 +IQsat(const iq10 &A, const iq10 &Pos, const iq10 &Neg) +{ + iq10 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq9 +IQsat(const iq9 &A, const iq9 &Pos, const iq9 &Neg) +{ + iq9 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq8 +IQsat(const iq8 &A, const iq8 &Pos, const iq8 &Neg) +{ + iq8 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq7 +IQsat(const iq7 &A, const iq7 &Pos, const iq7 &Neg) +{ + iq7 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq6 +IQsat(const iq6 &A, const iq6 &Pos, const iq6 &Neg) +{ + iq6 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq5 +IQsat(const iq5 &A, const iq5 &Pos, const iq5 &Neg) +{ + iq5 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq4 +IQsat(const iq4 &A, const iq4 &Pos, const iq4 &Neg) +{ + iq4 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq3 +IQsat(const iq3 &A, const iq3 &Pos, const iq3 &Neg) +{ + iq3 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq2 +IQsat(const iq2 &A, const iq2 &Pos, const iq2 &Neg) +{ + iq2 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq1 +IQsat(const iq1 &A, const iq1 &Pos, const iq1 &Neg) +{ + iq1 B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +inline iq +IQsat(const iq &A, const iq &Pos, const iq &Neg) +{ + iq B; + B.val = _IQsat(A.val, Pos.val, Neg.val); + return(B); +} + +//***************************************************************************** +// +// Converts an IQ number between the global IQ format and a specified IQ +// format. +// +//***************************************************************************** +inline iq30 +IQtoIQ30(const iq &A) +{ + iq30 B; + B.val = _IQtoIQ30(A.val); + return(B); +} + +inline iq +IQ30toIQ(const iq30 &A) +{ + iq B; + B.val = _IQ30toIQ(A.val); + return(B); +} + +inline iq29 +IQtoIQ29(const iq &A) +{ + iq29 B; + B.val = _IQtoIQ29(A.val); + return(B); +} + +inline iq +IQ29toIQ(const iq29 &A) +{ + iq B; + B.val = _IQ29toIQ(A.val); + return(B); +} + +inline iq28 +IQtoIQ28(const iq &A) +{ + iq28 B; + B.val = _IQtoIQ28(A.val); + return(B); +} + +inline iq +IQ28toIQ(const iq28 &A) +{ + iq B; + B.val = _IQ28toIQ(A.val); + return(B); +} + +inline iq27 +IQtoIQ27(const iq &A) +{ + iq27 B; + B.val = _IQtoIQ27(A.val); + return(B); +} + +inline iq +IQ27toIQ(const iq27 &A) +{ + iq B; + B.val = _IQ27toIQ(A.val); + return(B); +} + +inline iq26 +IQtoIQ26(const iq &A) +{ + iq26 B; + B.val = _IQtoIQ26(A.val); + return(B); +} + +inline iq +IQ26toIQ(const iq26 &A) +{ + iq B; + B.val = _IQ26toIQ(A.val); + return(B); +} + +inline iq25 +IQtoIQ25(const iq &A) +{ + iq25 B; + B.val = _IQtoIQ25(A.val); + return(B); +} + +inline iq +IQ25toIQ(const iq25 &A) +{ + iq B; + B.val = _IQ25toIQ(A.val); + return(B); +} + +inline iq24 +IQtoIQ24(const iq &A) +{ + iq24 B; + B.val = _IQtoIQ24(A.val); + return(B); +} + +inline iq +IQ24toIQ(const iq24 &A) +{ + iq B; + B.val = _IQ24toIQ(A.val); + return(B); +} + +inline iq23 +IQtoIQ23(const iq &A) +{ + iq23 B; + B.val = _IQtoIQ23(A.val); + return(B); +} + +inline iq +IQ23toIQ(const iq23 &A) +{ + iq B; + B.val = _IQ23toIQ(A.val); + return(B); +} + +inline iq22 +IQtoIQ22(const iq &A) +{ + iq22 B; + B.val = _IQtoIQ22(A.val); + return(B); +} + +inline iq +IQ22toIQ(const iq22 &A) +{ + iq B; + B.val = _IQ22toIQ(A.val); + return(B); +} + +inline iq21 +IQtoIQ21(const iq &A) +{ + iq21 B; + B.val = _IQtoIQ21(A.val); + return(B); +} + +inline iq +IQ21toIQ(const iq21 &A) +{ + iq B; + B.val = _IQ21toIQ(A.val); + return(B); +} + +inline iq20 +IQtoIQ20(const iq &A) +{ + iq20 B; + B.val = _IQtoIQ20(A.val); + return(B); +} + +inline iq +IQ20toIQ(const iq20 &A) +{ + iq B; + B.val = _IQ20toIQ(A.val); + return(B); +} + +inline iq19 +IQtoIQ19(const iq &A) +{ + iq19 B; + B.val = _IQtoIQ19(A.val); + return(B); +} + +inline iq +IQ19toIQ(const iq19 &A) +{ + iq B; + B.val = _IQ19toIQ(A.val); + return(B); +} + +inline iq18 +IQtoIQ18(const iq &A) +{ + iq18 B; + B.val = _IQtoIQ18(A.val); + return(B); +} + +inline iq +IQ18toIQ(const iq18 &A) +{ + iq B; + B.val = _IQ18toIQ(A.val); + return(B); +} + +inline iq17 +IQtoIQ17(const iq &A) +{ + iq17 B; + B.val = _IQtoIQ17(A.val); + return(B); +} + +inline iq +IQ17toIQ(const iq17 &A) +{ + iq B; + B.val = _IQ17toIQ(A.val); + return(B); +} + +inline iq16 +IQtoIQ16(const iq &A) +{ + iq16 B; + B.val = _IQtoIQ16(A.val); + return(B); +} + +inline iq +IQ16toIQ(const iq16 &A) +{ + iq B; + B.val = _IQ16toIQ(A.val); + return(B); +} + +inline iq15 +IQtoIQ15(const iq &A) +{ + iq15 B; + B.val = _IQtoIQ15(A.val); + return(B); +} + +inline iq +IQ15toIQ(const iq15 &A) +{ + iq B; + B.val = _IQ15toIQ(A.val); + return(B); +} + +inline iq14 +IQtoIQ14(const iq &A) +{ + iq14 B; + B.val = _IQtoIQ14(A.val); + return(B); +} + +inline iq +IQ14toIQ(const iq14 &A) +{ + iq B; + B.val = _IQ14toIQ(A.val); + return(B); +} + +inline iq13 +IQtoIQ13(const iq &A) +{ + iq13 B; + B.val = _IQtoIQ13(A.val); + return(B); +} + +inline iq +IQ13toIQ(const iq13 &A) +{ + iq B; + B.val = _IQ13toIQ(A.val); + return(B); +} + +inline iq12 +IQtoIQ12(const iq &A) +{ + iq12 B; + B.val = _IQtoIQ12(A.val); + return(B); +} + +inline iq +IQ12toIQ(const iq12 &A) +{ + iq B; + B.val = _IQ12toIQ(A.val); + return(B); +} + +inline iq11 +IQtoIQ11(const iq &A) +{ + iq11 B; + B.val = _IQtoIQ11(A.val); + return(B); +} + +inline iq +IQ11toIQ(const iq11 &A) +{ + iq B; + B.val = _IQ11toIQ(A.val); + return(B); +} + +inline iq10 +IQtoIQ10(const iq &A) +{ + iq10 B; + B.val = _IQtoIQ10(A.val); + return(B); +} + +inline iq +IQ10toIQ(const iq10 &A) +{ + iq B; + B.val = _IQ10toIQ(A.val); + return(B); +} + +inline iq9 +IQtoIQ9(const iq &A) +{ + iq9 B; + B.val = _IQtoIQ9(A.val); + return(B); +} + +inline iq +IQ9toIQ(const iq9 &A) +{ + iq B; + B.val = _IQ9toIQ(A.val); + return(B); +} + +inline iq8 +IQtoIQ8(const iq &A) +{ + iq8 B; + B.val = _IQtoIQ8(A.val); + return(B); +} + +inline iq +IQ8toIQ(const iq8 &A) +{ + iq B; + B.val = _IQ8toIQ(A.val); + return(B); +} + +inline iq7 +IQtoIQ7(const iq &A) +{ + iq7 B; + B.val = _IQtoIQ7(A.val); + return(B); +} + +inline iq +IQ7toIQ(const iq7 &A) +{ + iq B; + B.val = _IQ7toIQ(A.val); + return(B); +} + +inline iq6 +IQtoIQ6(const iq &A) +{ + iq6 B; + B.val = _IQtoIQ6(A.val); + return(B); +} + +inline iq +IQ6toIQ(const iq6 &A) +{ + iq B; + B.val = _IQ6toIQ(A.val); + return(B); +} + +inline iq5 +IQtoIQ5(const iq &A) +{ + iq5 B; + B.val = _IQtoIQ5(A.val); + return(B); +} + +inline iq +IQ5toIQ(const iq5 &A) +{ + iq B; + B.val = _IQ5toIQ(A.val); + return(B); +} + +inline iq4 +IQtoIQ4(const iq &A) +{ + iq4 B; + B.val = _IQtoIQ4(A.val); + return(B); +} + +inline iq +IQ4toIQ(const iq4 &A) +{ + iq B; + B.val = _IQ4toIQ(A.val); + return(B); +} + +inline iq3 +IQtoIQ3(const iq &A) +{ + iq3 B; + B.val = _IQtoIQ3(A.val); + return(B); +} + +inline iq +IQ3toIQ(const iq3 &A) +{ + iq B; + B.val = _IQ3toIQ(A.val); + return(B); +} + +inline iq2 +IQtoIQ2(const iq &A) +{ + iq2 B; + B.val = _IQtoIQ2(A.val); + return(B); +} + +inline iq +IQ2toIQ(const iq2 &A) +{ + iq B; + B.val = _IQ2toIQ(A.val); + return(B); +} + +inline iq1 +IQtoIQ1(const iq &A) +{ + iq1 B; + B.val = _IQtoIQ1(A.val); + return(B); +} + +inline iq +IQ1toIQ(const iq1 &A) +{ + iq B; + B.val = _IQ1toIQ(A.val); + return(B); +} + + +//***************************************************************************** +// +// Converts a number between IQ format and 16-bit Qn format. +// +//***************************************************************************** +inline long +IQtoQ15(const iq &A) +{ + return(_IQtoQ15(A.val)); +} + +inline iq +Q15toIQ(long A) +{ + iq B; + B.val = _Q15toIQ(A); + return(B); +} + +inline long +IQtoQ14(const iq &A) +{ + return(_IQtoQ14(A.val)); +} + +inline iq +Q14toIQ(long A) +{ + iq B; + B.val = _Q14toIQ(A); + return(B); +} + +inline long +IQtoQ13(const iq &A) +{ + return(_IQtoQ13(A.val)); +} + +inline iq +Q13toIQ(long A) +{ + iq B; + B.val = _Q13toIQ(A); + return(B); +} + +inline long +IQtoQ12(const iq &A) +{ + return(_IQtoQ12(A.val)); +} + +inline iq +Q12toIQ(long A) +{ + iq B; + B.val = _Q12toIQ(A); + return(B); +} + +inline long +IQtoQ11(const iq &A) +{ + return(_IQtoQ11(A.val)); +} + +inline iq +Q11toIQ(long A) +{ + iq B; + B.val = _Q11toIQ(A); + return(B); +} + +inline long +IQtoQ10(const iq &A) +{ + return(_IQtoQ10(A.val)); +} + +inline iq +Q10toIQ(long A) +{ + iq B; + B.val = _Q10toIQ(A); + return(B); +} + +inline long +IQtoQ9(const iq &A) +{ + return(_IQtoQ9(A.val)); +} + +inline iq +Q9toIQ(long A) +{ + iq B; + B.val = _Q9toIQ(A); + return(B); +} + +inline long +IQtoQ8(const iq &A) +{ + return(_IQtoQ8(A.val)); +} + +inline iq +Q8toIQ(long A) +{ + iq B; + B.val = _Q8toIQ(A); + return(B); +} + +inline long +IQtoQ7(const iq &A) +{ + return(_IQtoQ7(A.val)); +} + +inline iq +Q7toIQ(long A) +{ + iq B; + B.val = _Q7toIQ(A); + return(B); +} + +inline long +IQtoQ6(const iq &A) +{ + return(_IQtoQ6(A.val)); +} + +inline iq +Q6toIQ(long A) +{ + iq B; + B.val = _Q6toIQ(A); + return(B); +} + +inline long +IQtoQ5(const iq &A) +{ + return(_IQtoQ5(A.val)); +} + +inline iq +Q5toIQ(long A) +{ + iq B; + B.val = _Q5toIQ(A); + return(B); +} + +inline long +IQtoQ4(const iq &A) +{ + return(_IQtoQ4(A.val)); +} + +inline iq +Q4toIQ(long A) +{ + iq B; + B.val = _Q4toIQ(A); + return(B); +} + +inline long +IQtoQ3(const iq &A) +{ + return(_IQtoQ3(A.val)); +} + +inline iq +Q3toIQ(long A) +{ + iq B; + B.val = _Q3toIQ(A); + return(B); +} + +inline long +IQtoQ2(const iq &A) +{ + return(_IQtoQ2(A.val)); +} + +inline iq +Q2toIQ(long A) +{ + iq B; + B.val = _Q2toIQ(A); + return(B); +} + +inline long +IQtoQ1(const iq &A) +{ + return(_IQtoQ1(A.val)); +} + +inline iq +Q1toIQ(long A) +{ + iq B; + B.val = _Q1toIQ(A); + return(B); +} + + +//***************************************************************************** +// +// Converts an IQ number into a string. +// +//***************************************************************************** +inline int +IQ30toa(char *A, const char *B, const iq30 &C) +{ + return(__IQNtoa(A, B, C.val, 30)); +} + +inline int +IQ29toa(char *A, const char *B, const iq29 &C) +{ + return(__IQNtoa(A, B, C.val, 29)); +} + +inline int +IQ28toa(char *A, const char *B, const iq28 &C) +{ + return(__IQNtoa(A, B, C.val, 28)); +} + +inline int +IQ27toa(char *A, const char *B, const iq27 &C) +{ + return(__IQNtoa(A, B, C.val, 27)); +} + +inline int +IQ26toa(char *A, const char *B, const iq26 &C) +{ + return(__IQNtoa(A, B, C.val, 26)); +} + +inline int +IQ25toa(char *A, const char *B, const iq25 &C) +{ + return(__IQNtoa(A, B, C.val, 25)); +} + +inline int +IQ24toa(char *A, const char *B, const iq24 &C) +{ + return(__IQNtoa(A, B, C.val, 24)); +} + +inline int +IQ23toa(char *A, const char *B, const iq23 &C) +{ + return(__IQNtoa(A, B, C.val, 23)); +} + +inline int +IQ22toa(char *A, const char *B, const iq22 &C) +{ + return(__IQNtoa(A, B, C.val, 22)); +} + +inline int +IQ21toa(char *A, const char *B, const iq21 &C) +{ + return(__IQNtoa(A, B, C.val, 21)); +} + +inline int +IQ20toa(char *A, const char *B, const iq20 &C) +{ + return(__IQNtoa(A, B, C.val, 20)); +} + +inline int +IQ19toa(char *A, const char *B, const iq19 &C) +{ + return(__IQNtoa(A, B, C.val, 19)); +} + +inline int +IQ18toa(char *A, const char *B, const iq18 &C) +{ + return(__IQNtoa(A, B, C.val, 18)); +} + +inline int +IQ17toa(char *A, const char *B, const iq17 &C) +{ + return(__IQNtoa(A, B, C.val, 17)); +} + +inline int +IQ16toa(char *A, const char *B, const iq16 &C) +{ + return(__IQNtoa(A, B, C.val, 16)); +} + +inline int +IQ15toa(char *A, const char *B, const iq15 &C) +{ + return(__IQNtoa(A, B, C.val, 15)); +} + +inline int +IQ14toa(char *A, const char *B, const iq14 &C) +{ + return(__IQNtoa(A, B, C.val, 14)); +} + +inline int +IQ13toa(char *A, const char *B, const iq13 &C) +{ + return(__IQNtoa(A, B, C.val, 13)); +} + +inline int +IQ12toa(char *A, const char *B, const iq12 &C) +{ + return(__IQNtoa(A, B, C.val, 12)); +} + +inline int +IQ11toa(char *A, const char *B, const iq11 &C) +{ + return(__IQNtoa(A, B, C.val, 11)); +} + +inline int +IQ10toa(char *A, const char *B, const iq10 &C) +{ + return(__IQNtoa(A, B, C.val, 10)); +} + +inline int +IQ9toa(char *A, const char *B, const iq9 &C) +{ + return(__IQNtoa(A, B, C.val, 9)); +} + +inline int +IQ8toa(char *A, const char *B, const iq8 &C) +{ + return(__IQNtoa(A, B, C.val, 8)); +} + +inline int +IQ7toa(char *A, const char *B, const iq7 &C) +{ + return(__IQNtoa(A, B, C.val, 7)); +} + +inline int +IQ6toa(char *A, const char *B, const iq6 &C) +{ + return(__IQNtoa(A, B, C.val, 6)); +} + +inline int +IQ5toa(char *A, const char *B, const iq5 &C) +{ + return(__IQNtoa(A, B, C.val, 5)); +} + +inline int +IQ4toa(char *A, const char *B, const iq4 &C) +{ + return(__IQNtoa(A, B, C.val, 4)); +} + +inline int +IQ3toa(char *A, const char *B, const iq3 &C) +{ + return(__IQNtoa(A, B, C.val, 3)); +} + +inline int +IQ2toa(char *A, const char *B, const iq2 &C) +{ + return(__IQNtoa(A, B, C.val, 2)); +} + +inline int +IQ1toa(char *A, const char *B, const iq1 &C) +{ + return(__IQNtoa(A, B, C.val, 1)); +} + +inline int +IQtoa(char *A, const char *B, const iq &C) +{ + return(__IQNtoa(A, B, C.val, GLOBAL_Q)); +} + +//***************************************************************************** +// +// Converts a string into an IQ number. +// +//***************************************************************************** +inline iq30 +atoIQ30(const char *A) +{ + iq30 B; + B.val = _atoIQ30(A); + return(B); +} + +inline iq29 +atoIQ29(const char *A) +{ + iq29 B; + B.val = _atoIQ29(A); + return(B); +} + +inline iq28 +atoIQ28(const char *A) +{ + iq28 B; + B.val = _atoIQ28(A); + return(B); +} + +inline iq27 +atoIQ27(const char *A) +{ + iq27 B; + B.val = _atoIQ27(A); + return(B); +} + +inline iq26 +atoIQ26(const char *A) +{ + iq26 B; + B.val = _atoIQ26(A); + return(B); +} + +inline iq25 +atoIQ25(const char *A) +{ + iq25 B; + B.val = _atoIQ25(A); + return(B); +} + +inline iq24 +atoIQ24(const char *A) +{ + iq24 B; + B.val = _atoIQ24(A); + return(B); +} + +inline iq23 +atoIQ23(const char *A) +{ + iq23 B; + B.val = _atoIQ23(A); + return(B); +} + +inline iq22 +atoIQ22(const char *A) +{ + iq22 B; + B.val = _atoIQ22(A); + return(B); +} + +inline iq21 +atoIQ21(const char *A) +{ + iq21 B; + B.val = _atoIQ21(A); + return(B); +} + +inline iq20 +atoIQ20(const char *A) +{ + iq20 B; + B.val = _atoIQ20(A); + return(B); +} + +inline iq19 +atoIQ19(const char *A) +{ + iq19 B; + B.val = _atoIQ19(A); + return(B); +} + +inline iq18 +atoIQ18(const char *A) +{ + iq18 B; + B.val = _atoIQ18(A); + return(B); +} + +inline iq17 +atoIQ17(const char *A) +{ + iq17 B; + B.val = _atoIQ17(A); + return(B); +} + +inline iq16 +atoIQ16(const char *A) +{ + iq16 B; + B.val = _atoIQ16(A); + return(B); +} + +inline iq15 +atoIQ15(const char *A) +{ + iq15 B; + B.val = _atoIQ15(A); + return(B); +} + +inline iq14 +atoIQ14(const char *A) +{ + iq14 B; + B.val = _atoIQ14(A); + return(B); +} + +inline iq13 +atoIQ13(const char *A) +{ + iq13 B; + B.val = _atoIQ13(A); + return(B); +} + +inline iq12 +atoIQ12(const char *A) +{ + iq12 B; + B.val = _atoIQ12(A); + return(B); +} + +inline iq11 +atoIQ11(const char *A) +{ + iq11 B; + B.val = _atoIQ11(A); + return(B); +} + +inline iq10 +atoIQ10(const char *A) +{ + iq10 B; + B.val = _atoIQ10(A); + return(B); +} + +inline iq9 +atoIQ9(const char *A) +{ + iq9 B; + B.val = _atoIQ9(A); + return(B); +} + +inline iq8 +atoIQ8(const char *A) +{ + iq8 B; + B.val = _atoIQ8(A); + return(B); +} + +inline iq7 +atoIQ7(const char *A) +{ + iq7 B; + B.val = _atoIQ7(A); + return(B); +} + +inline iq6 +atoIQ6(const char *A) +{ + iq6 B; + B.val = _atoIQ6(A); + return(B); +} + +inline iq5 +atoIQ5(const char *A) +{ + iq5 B; + B.val = _atoIQ5(A); + return(B); +} + +inline iq4 +atoIQ4(const char *A) +{ + iq4 B; + B.val = _atoIQ4(A); + return(B); +} + +inline iq3 +atoIQ3(const char *A) +{ + iq3 B; + B.val = _atoIQ3(A); + return(B); +} + +inline iq2 +atoIQ2(const char *A) +{ + iq2 B; + B.val = _atoIQ2(A); + return(B); +} + +inline iq1 +atoIQ1(const char *A) +{ + iq1 B; + B.val = _atoIQ1(A); + return(B); +} + +inline iq +atoIQ(const char *A) +{ + iq B; + B.val = _atoIQ(A); + return(B); +} + +//***************************************************************************** +// +// Returns the integer portion of an IQ number. +// +//***************************************************************************** +inline long +IQ30int(const iq30 &A) +{ + return(_IQ30int(A.val)); +} + +inline long +IQ29int(const iq29 &A) +{ + return(_IQ29int(A.val)); +} + +inline long +IQ28int(const iq28 &A) +{ + return(_IQ28int(A.val)); +} + +inline long +IQ27int(const iq27 &A) +{ + return(_IQ27int(A.val)); +} + +inline long +IQ26int(const iq26 &A) +{ + return(_IQ26int(A.val)); +} + +inline long +IQ25int(const iq25 &A) +{ + return(_IQ25int(A.val)); +} + +inline long +IQ24int(const iq24 &A) +{ + return(_IQ24int(A.val)); +} + +inline long +IQ23int(const iq23 &A) +{ + return(_IQ23int(A.val)); +} + +inline long +IQ22int(const iq22 &A) +{ + return(_IQ22int(A.val)); +} + +inline long +IQ21int(const iq21 &A) +{ + return(_IQ21int(A.val)); +} + +inline long +IQ20int(const iq20 &A) +{ + return(_IQ20int(A.val)); +} + +inline long +IQ19int(const iq19 &A) +{ + return(_IQ19int(A.val)); +} + +inline long +IQ18int(const iq18 &A) +{ + return(_IQ18int(A.val)); +} + +inline long +IQ17int(const iq17 &A) +{ + return(_IQ17int(A.val)); +} + +inline long +IQ16int(const iq16 &A) +{ + return(_IQ16int(A.val)); +} + +inline long +IQ15int(const iq15 &A) +{ + return(_IQ15int(A.val)); +} + +inline long +IQ14int(const iq14 &A) +{ + return(_IQ14int(A.val)); +} + +inline long +IQ13int(const iq13 &A) +{ + return(_IQ13int(A.val)); +} + +inline long +IQ12int(const iq12 &A) +{ + return(_IQ12int(A.val)); +} + +inline long +IQ11int(const iq11 &A) +{ + return(_IQ11int(A.val)); +} + +inline long +IQ10int(const iq10 &A) +{ + return(_IQ10int(A.val)); +} + +inline long +IQ9int(const iq9 &A) +{ + return(_IQ9int(A.val)); +} + +inline long +IQ8int(const iq8 &A) +{ + return(_IQ8int(A.val)); +} + +inline long +IQ7int(const iq7 &A) +{ + return(_IQ7int(A.val)); +} + +inline long +IQ6int(const iq6 &A) +{ + return(_IQ6int(A.val)); +} + +inline long +IQ5int(const iq5 &A) +{ + return(_IQ5int(A.val)); +} + +inline long +IQ4int(const iq4 &A) +{ + return(_IQ4int(A.val)); +} + +inline long +IQ3int(const iq3 &A) +{ + return(_IQ3int(A.val)); +} + +inline long +IQ2int(const iq2 &A) +{ + return(_IQ2int(A.val)); +} + +inline long +IQ1int(const iq1 &A) +{ + return(_IQ1int(A.val)); +} + +inline long +IQint(const iq &A) +{ + return(_IQint(A.val)); +} + +//***************************************************************************** +// +// Computes the fractional portion of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30frac(const iq30 &A) +{ + iq30 B; + B.val = _IQ30frac(A.val); + return(B); +} + +inline iq29 +IQ29frac(const iq29 &A) +{ + iq29 B; + B.val = _IQ29frac(A.val); + return(B); +} + +inline iq28 +IQ28frac(const iq28 &A) +{ + iq28 B; + B.val = _IQ28frac(A.val); + return(B); +} + +inline iq27 +IQ27frac(const iq27 &A) +{ + iq27 B; + B.val = _IQ27frac(A.val); + return(B); +} + +inline iq26 +IQ26frac(const iq26 &A) +{ + iq26 B; + B.val = _IQ26frac(A.val); + return(B); +} + +inline iq25 +IQ25frac(const iq25 &A) +{ + iq25 B; + B.val = _IQ25frac(A.val); + return(B); +} + +inline iq24 +IQ24frac(const iq24 &A) +{ + iq24 B; + B.val = _IQ24frac(A.val); + return(B); +} + +inline iq23 +IQ23frac(const iq23 &A) +{ + iq23 B; + B.val = _IQ23frac(A.val); + return(B); +} + +inline iq22 +IQ22frac(const iq22 &A) +{ + iq22 B; + B.val = _IQ22frac(A.val); + return(B); +} + +inline iq21 +IQ21frac(const iq21 &A) +{ + iq21 B; + B.val = _IQ21frac(A.val); + return(B); +} + +inline iq20 +IQ20frac(const iq20 &A) +{ + iq20 B; + B.val = _IQ20frac(A.val); + return(B); +} + +inline iq19 +IQ19frac(const iq19 &A) +{ + iq19 B; + B.val = _IQ19frac(A.val); + return(B); +} + +inline iq18 +IQ18frac(const iq18 &A) +{ + iq18 B; + B.val = _IQ18frac(A.val); + return(B); +} + +inline iq17 +IQ17frac(const iq17 &A) +{ + iq17 B; + B.val = _IQ17frac(A.val); + return(B); +} + +inline iq16 +IQ16frac(const iq16 &A) +{ + iq16 B; + B.val = _IQ16frac(A.val); + return(B); +} + +inline iq15 +IQ15frac(const iq15 &A) +{ + iq15 B; + B.val = _IQ15frac(A.val); + return(B); +} + +inline iq14 +IQ14frac(const iq14 &A) +{ + iq14 B; + B.val = _IQ14frac(A.val); + return(B); +} + +inline iq13 +IQ13frac(const iq13 &A) +{ + iq13 B; + B.val = _IQ13frac(A.val); + return(B); +} + +inline iq12 +IQ12frac(const iq12 &A) +{ + iq12 B; + B.val = _IQ12frac(A.val); + return(B); +} + +inline iq11 +IQ11frac(const iq11 &A) +{ + iq11 B; + B.val = _IQ11frac(A.val); + return(B); +} + +inline iq10 +IQ10frac(const iq10 &A) +{ + iq10 B; + B.val = _IQ10frac(A.val); + return(B); +} + +inline iq9 +IQ9frac(const iq9 &A) +{ + iq9 B; + B.val = _IQ9frac(A.val); + return(B); +} + +inline iq8 +IQ8frac(const iq8 &A) +{ + iq8 B; + B.val = _IQ8frac(A.val); + return(B); +} + +inline iq7 +IQ7frac(const iq7 &A) +{ + iq7 B; + B.val = _IQ7frac(A.val); + return(B); +} + +inline iq6 +IQ6frac(const iq6 &A) +{ + iq6 B; + B.val = _IQ6frac(A.val); + return(B); +} + +inline iq5 +IQ5frac(const iq5 &A) +{ + iq5 B; + B.val = _IQ5frac(A.val); + return(B); +} + +inline iq4 +IQ4frac(const iq4 &A) +{ + iq4 B; + B.val = _IQ4frac(A.val); + return(B); +} + +inline iq3 +IQ3frac(const iq3 &A) +{ + iq3 B; + B.val = _IQ3frac(A.val); + return(B); +} + +inline iq2 +IQ2frac(const iq2 &A) +{ + iq2 B; + B.val = _IQ2frac(A.val); + return(B); +} + +inline iq1 +IQ1frac(const iq1 &A) +{ + iq1 B; + B.val = _IQ1frac(A.val); + return(B); +} + +inline iq +IQfrac(const iq &A) +{ + iq B; + B.val = _IQfrac(A.val); + return(B); +} + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding. +// +//***************************************************************************** +inline iq30 +IQ30rmpy(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30rmpy(A.val, B.val); + return(C); +} + +inline iq29 +IQ29rmpy(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29rmpy(A.val, B.val); + return(C); +} + +inline iq28 +IQ28rmpy(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28rmpy(A.val, B.val); + return(C); +} + +inline iq27 +IQ27rmpy(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27rmpy(A.val, B.val); + return(C); +} + +inline iq26 +IQ26rmpy(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26rmpy(A.val, B.val); + return(C); +} + +inline iq25 +IQ25rmpy(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25rmpy(A.val, B.val); + return(C); +} + +inline iq24 +IQ24rmpy(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24rmpy(A.val, B.val); + return(C); +} + +inline iq23 +IQ23rmpy(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23rmpy(A.val, B.val); + return(C); +} + +inline iq22 +IQ22rmpy(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22rmpy(A.val, B.val); + return(C); +} + +inline iq21 +IQ21rmpy(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21rmpy(A.val, B.val); + return(C); +} + +inline iq20 +IQ20rmpy(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20rmpy(A.val, B.val); + return(C); +} + +inline iq19 +IQ19rmpy(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19rmpy(A.val, B.val); + return(C); +} + +inline iq18 +IQ18rmpy(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18rmpy(A.val, B.val); + return(C); +} + +inline iq17 +IQ17rmpy(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17rmpy(A.val, B.val); + return(C); +} + +inline iq16 +IQ16rmpy(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16rmpy(A.val, B.val); + return(C); +} + +inline iq15 +IQ15rmpy(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15rmpy(A.val, B.val); + return(C); +} + +inline iq14 +IQ14rmpy(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14rmpy(A.val, B.val); + return(C); +} + +inline iq13 +IQ13rmpy(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13rmpy(A.val, B.val); + return(C); +} + +inline iq12 +IQ12rmpy(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12rmpy(A.val, B.val); + return(C); +} + +inline iq11 +IQ11rmpy(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11rmpy(A.val, B.val); + return(C); +} + +inline iq10 +IQ10rmpy(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10rmpy(A.val, B.val); + return(C); +} + +inline iq9 +IQ9rmpy(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9rmpy(A.val, B.val); + return(C); +} + +inline iq8 +IQ8rmpy(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8rmpy(A.val, B.val); + return(C); +} + +inline iq7 +IQ7rmpy(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7rmpy(A.val, B.val); + return(C); +} + +inline iq6 +IQ6rmpy(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6rmpy(A.val, B.val); + return(C); +} + +inline iq5 +IQ5rmpy(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5rmpy(A.val, B.val); + return(C); +} + +inline iq4 +IQ4rmpy(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4rmpy(A.val, B.val); + return(C); +} + +inline iq3 +IQ3rmpy(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3rmpy(A.val, B.val); + return(C); +} + +inline iq2 +IQ2rmpy(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2rmpy(A.val, B.val); + return(C); +} + +inline iq1 +IQ1rmpy(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1rmpy(A.val, B.val); + return(C); +} + +inline iq +IQrmpy(const iq &A, const iq &B) +{ + iq C; + C.val = _IQrmpy(A.val, B.val); + return(C); +} + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding and saturation. +// +//***************************************************************************** +inline iq30 +IQ30rsmpy(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30rsmpy(A.val, B.val); + return(C); +} + +inline iq29 +IQ29rsmpy(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29rsmpy(A.val, B.val); + return(C); +} + +inline iq28 +IQ28rsmpy(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28rsmpy(A.val, B.val); + return(C); +} + +inline iq27 +IQ27rsmpy(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27rsmpy(A.val, B.val); + return(C); +} + +inline iq26 +IQ26rsmpy(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26rsmpy(A.val, B.val); + return(C); +} + +inline iq25 +IQ25rsmpy(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25rsmpy(A.val, B.val); + return(C); +} + +inline iq24 +IQ24rsmpy(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24rsmpy(A.val, B.val); + return(C); +} + +inline iq23 +IQ23rsmpy(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23rsmpy(A.val, B.val); + return(C); +} + +inline iq22 +IQ22rsmpy(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22rsmpy(A.val, B.val); + return(C); +} + +inline iq21 +IQ21rsmpy(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21rsmpy(A.val, B.val); + return(C); +} + +inline iq20 +IQ20rsmpy(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20rsmpy(A.val, B.val); + return(C); +} + +inline iq19 +IQ19rsmpy(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19rsmpy(A.val, B.val); + return(C); +} + +inline iq18 +IQ18rsmpy(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18rsmpy(A.val, B.val); + return(C); +} + +inline iq17 +IQ17rsmpy(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17rsmpy(A.val, B.val); + return(C); +} + +inline iq16 +IQ16rsmpy(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16rsmpy(A.val, B.val); + return(C); +} + +inline iq15 +IQ15rsmpy(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15rsmpy(A.val, B.val); + return(C); +} + +inline iq14 +IQ14rsmpy(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14rsmpy(A.val, B.val); + return(C); +} + +inline iq13 +IQ13rsmpy(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13rsmpy(A.val, B.val); + return(C); +} + +inline iq12 +IQ12rsmpy(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12rsmpy(A.val, B.val); + return(C); +} + +inline iq11 +IQ11rsmpy(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11rsmpy(A.val, B.val); + return(C); +} + +inline iq10 +IQ10rsmpy(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10rsmpy(A.val, B.val); + return(C); +} + +inline iq9 +IQ9rsmpy(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9rsmpy(A.val, B.val); + return(C); +} + +inline iq8 +IQ8rsmpy(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8rsmpy(A.val, B.val); + return(C); +} + +inline iq7 +IQ7rsmpy(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7rsmpy(A.val, B.val); + return(C); +} + +inline iq6 +IQ6rsmpy(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6rsmpy(A.val, B.val); + return(C); +} + +inline iq5 +IQ5rsmpy(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5rsmpy(A.val, B.val); + return(C); +} + +inline iq4 +IQ4rsmpy(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4rsmpy(A.val, B.val); + return(C); +} + +inline iq3 +IQ3rsmpy(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3rsmpy(A.val, B.val); + return(C); +} + +inline iq2 +IQ2rsmpy(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2rsmpy(A.val, B.val); + return(C); +} + +inline iq1 +IQ1rsmpy(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1rsmpy(A.val, B.val); + return(C); +} + +inline iq +IQrsmpy(const iq &A, const iq &B) +{ + iq C; + C.val = _IQrsmpy(A.val, B.val); + return(C); +} + +//***************************************************************************** +// +// Multiplies two IQ numbers in the specified iQ formats, returning the result +// in another IQ format. +// +//***************************************************************************** +#define IQ30mpyIQX(A, IQA, B, IQB) ((iq30)__IQxmpy(A.val, B.val, \ + (30 + 32 - IQA - IQB))) +#define IQ29mpyIQX(A, IQA, B, IQB) ((iq29)__IQxmpy(A.val, B.val, \ + (29 + 32 - IQA - IQB))) +#define IQ28mpyIQX(A, IQA, B, IQB) ((iq28)__IQxmpy(A.val, B.val, \ + (28 + 32 - IQA - IQB))) +#define IQ27mpyIQX(A, IQA, B, IQB) ((iq27)__IQxmpy(A.val, B.val, \ + (27 + 32 - IQA - IQB))) +#define IQ26mpyIQX(A, IQA, B, IQB) ((iq26)__IQxmpy(A.val, B.val, \ + (26 + 32 - IQA - IQB))) +#define IQ25mpyIQX(A, IQA, B, IQB) ((iq25)__IQxmpy(A.val, B.val, \ + (25 + 32 - IQA - IQB))) +#define IQ24mpyIQX(A, IQA, B, IQB) ((iq24)__IQxmpy(A.val, B.val, \ + (24 + 32 - IQA - IQB))) +#define IQ23mpyIQX(A, IQA, B, IQB) ((iq23)__IQxmpy(A.val, B.val, \ + (23 + 32 - IQA - IQB))) +#define IQ22mpyIQX(A, IQA, B, IQB) ((iq22)__IQxmpy(A.val, B.val, \ + (22 + 32 - IQA - IQB))) +#define IQ21mpyIQX(A, IQA, B, IQB) ((iq21)__IQxmpy(A.val, B.val, \ + (21 + 32 - IQA - IQB))) +#define IQ20mpyIQX(A, IQA, B, IQB) ((iq20)__IQxmpy(A.val, B.val, \ + (20 + 32 - IQA - IQB))) +#define IQ19mpyIQX(A, IQA, B, IQB) ((iq19)__IQxmpy(A.val, B.val, \ + (19 + 32 - IQA - IQB))) +#define IQ18mpyIQX(A, IQA, B, IQB) ((iq18)__IQxmpy(A.val, B.val, \ + (18 + 32 - IQA - IQB))) +#define IQ17mpyIQX(A, IQA, B, IQB) ((iq17)__IQxmpy(A.val, B.val, \ + (17 + 32 - IQA - IQB))) +#define IQ16mpyIQX(A, IQA, B, IQB) ((iq16)__IQxmpy(A.val, B.val, \ + (16 + 32 - IQA - IQB))) +#define IQ15mpyIQX(A, IQA, B, IQB) ((iq15)__IQxmpy(A.val, B.val, \ + (15 + 32 - IQA - IQB))) +#define IQ14mpyIQX(A, IQA, B, IQB) ((iq14)__IQxmpy(A.val, B.val, \ + (14 + 32 - IQA - IQB))) +#define IQ13mpyIQX(A, IQA, B, IQB) ((iq13)__IQxmpy(A.val, B.val, \ + (13 + 32 - IQA - IQB))) +#define IQ12mpyIQX(A, IQA, B, IQB) ((iq12)__IQxmpy(A.val, B.val, \ + (12 + 32 - IQA - IQB))) +#define IQ11mpyIQX(A, IQA, B, IQB) ((iq11)__IQxmpy(A.val, B.val, \ + (11 + 32 - IQA - IQB))) +#define IQ10mpyIQX(A, IQA, B, IQB) ((iq10)__IQxmpy(A.val, B.val, \ + (10 + 32 - IQA - IQB))) +#define IQ9mpyIQX(A, IQA, B, IQB) ((iq9)__IQxmpy(A.val, B.val, \ + (9 + 32 - IQA - IQB))) +#define IQ8mpyIQX(A, IQA, B, IQB) ((iq8)__IQxmpy(A.val, B.val, \ + (8 + 32 - IQA - IQB))) +#define IQ7mpyIQX(A, IQA, B, IQB) ((iq7)__IQxmpy(A.val, B.val, \ + (7 + 32 - IQA - IQB))) +#define IQ6mpyIQX(A, IQA, B, IQB) ((iq6)__IQxmpy(A.val, B.val, \ + (6 + 32 - IQA - IQB))) +#define IQ5mpyIQX(A, IQA, B, IQB) ((iq5)__IQxmpy(A.val, B.val, \ + (5 + 32 - IQA - IQB))) +#define IQ4mpyIQX(A, IQA, B, IQB) ((iq4)__IQxmpy(A.val, B.val, \ + (4 + 32 - IQA - IQB))) +#define IQ3mpyIQX(A, IQA, B, IQB) ((iq3)__IQxmpy(A.val, B.val, \ + (3 + 32 - IQA - IQB))) +#define IQ2mpyIQX(A, IQA, B, IQB) ((iq2)__IQxmpy(A.val, B.val, \ + (2 + 32 - IQA - IQB))) +#define IQ1mpyIQX(A, IQA, B, IQB) ((iq1)__IQxmpy(A.val, B.val, \ + (1 + 32 - IQA - IQB))) +#define IQmpyIQX(A, IQA, B, IQB) ((iq)__IQxmpy(A.val, B.val, \ + (GLOBAL_Q + 32 - IQA - IQB))) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer. +// +//***************************************************************************** +inline iq30 +IQ30mpyI32(const iq30 &A, long B) +{ + iq30 C; + C.val = (A.val * B); + return(C); +} + +inline iq30 +IQ30mpyI32(long A, const iq30 &B) +{ + iq30 C; + C.val = (A * B.val); + return(C); +} + +inline iq29 +IQ29mpyI32(const iq29 &A, long B) +{ + iq29 C; + C.val = (A.val * B); + return(C); +} + +inline iq29 +IQ29mpyI32(long A, const iq29 &B) +{ + iq29 C; + C.val = (A * B.val); + return(C); +} + +inline iq28 +IQ28mpyI32(const iq28 &A, long B) +{ + iq28 C; + C.val = (A.val * B); + return(C); +} + +inline iq28 +IQ28mpyI32(long A, const iq28 &B) +{ + iq28 C; + C.val = (A * B.val); + return(C); +} + +inline iq27 +IQ27mpyI32(const iq27 &A, long B) +{ + iq27 C; + C.val = (A.val * B); + return(C); +} + +inline iq27 +IQ27mpyI32(long A, const iq27 &B) +{ + iq27 C; + C.val = (A * B.val); + return(C); +} + +inline iq26 +IQ26mpyI32(const iq26 &A, long B) +{ + iq26 C; + C.val = (A.val * B); + return(C); +} + +inline iq26 +IQ26mpyI32(long A, const iq26 &B) +{ + iq26 C; + C.val = (A * B.val); + return(C); +} + +inline iq25 +IQ25mpyI32(const iq25 &A, long B) +{ + iq25 C; + C.val = (A.val * B); + return(C); +} + +inline iq25 +IQ25mpyI32(long A, const iq25 &B) +{ + iq25 C; + C.val = (A * B.val); + return(C); +} + +inline iq24 +IQ24mpyI32(const iq24 &A, long B) +{ + iq24 C; + C.val = (A.val * B); + return(C); +} + +inline iq24 +IQ24mpyI32(long A, const iq24 &B) +{ + iq24 C; + C.val = (A * B.val); + return(C); +} + +inline iq23 +IQ23mpyI32(const iq23 &A, long B) +{ + iq23 C; + C.val = (A.val * B); + return(C); +} + +inline iq23 +IQ23mpyI32(long A, const iq23 &B) +{ + iq23 C; + C.val = (A * B.val); + return(C); +} + +inline iq22 +IQ22mpyI32(const iq22 &A, long B) +{ + iq22 C; + C.val = (A.val * B); + return(C); +} + +inline iq22 +IQ22mpyI32(long A, const iq22 &B) +{ + iq22 C; + C.val = (A * B.val); + return(C); +} + +inline iq21 +IQ21mpyI32(const iq21 &A, long B) +{ + iq21 C; + C.val = (A.val * B); + return(C); +} + +inline iq21 +IQ21mpyI32(long A, const iq21 &B) +{ + iq21 C; + C.val = (A * B.val); + return(C); +} + +inline iq20 +IQ20mpyI32(const iq20 &A, long B) +{ + iq20 C; + C.val = (A.val * B); + return(C); +} + +inline iq20 +IQ20mpyI32(long A, const iq20 &B) +{ + iq20 C; + C.val = (A * B.val); + return(C); +} + +inline iq19 +IQ19mpyI32(const iq19 &A, long B) +{ + iq19 C; + C.val = (A.val * B); + return(C); +} + +inline iq19 +IQ19mpyI32(long A, const iq19 &B) +{ + iq19 C; + C.val = (A * B.val); + return(C); +} + +inline iq18 +IQ18mpyI32(const iq18 &A, long B) +{ + iq18 C; + C.val = (A.val * B); + return(C); +} + +inline iq18 +IQ18mpyI32(long A, const iq18 &B) +{ + iq18 C; + C.val = (A * B.val); + return(C); +} + +inline iq17 +IQ17mpyI32(const iq17 &A, long B) +{ + iq17 C; + C.val = (A.val * B); + return(C); +} + +inline iq17 +IQ17mpyI32(long A, const iq17 &B) +{ + iq17 C; + C.val = (A * B.val); + return(C); +} + +inline iq16 +IQ16mpyI32(const iq16 &A, long B) +{ + iq16 C; + C.val = (A.val * B); + return(C); +} + +inline iq16 +IQ16mpyI32(long A, const iq16 &B) +{ + iq16 C; + C.val = (A * B.val); + return(C); +} + +inline iq15 +IQ15mpyI32(const iq15 &A, long B) +{ + iq15 C; + C.val = (A.val * B); + return(C); +} + +inline iq15 +IQ15mpyI32(long A, const iq15 &B) +{ + iq15 C; + C.val = (A * B.val); + return(C); +} + +inline iq14 +IQ14mpyI32(const iq14 &A, long B) +{ + iq14 C; + C.val = (A.val * B); + return(C); +} + +inline iq14 +IQ14mpyI32(long A, const iq14 &B) +{ + iq14 C; + C.val = (A * B.val); + return(C); +} + +inline iq13 +IQ13mpyI32(const iq13 &A, long B) +{ + iq13 C; + C.val = (A.val * B); + return(C); +} + +inline iq13 +IQ13mpyI32(long A, const iq13 &B) +{ + iq13 C; + C.val = (A * B.val); + return(C); +} + +inline iq12 +IQ12mpyI32(const iq12 &A, long B) +{ + iq12 C; + C.val = (A.val * B); + return(C); +} + +inline iq12 +IQ12mpyI32(long A, const iq12 &B) +{ + iq12 C; + C.val = (A * B.val); + return(C); +} + +inline iq11 +IQ11mpyI32(const iq11 &A, long B) +{ + iq11 C; + C.val = (A.val * B); + return(C); +} + +inline iq11 +IQ11mpyI32(long A, const iq11 &B) +{ + iq11 C; + C.val = (A * B.val); + return(C); +} + +inline iq10 +IQ10mpyI32(const iq10 &A, long B) +{ + iq10 C; + C.val = (A.val * B); + return(C); +} + +inline iq10 +IQ10mpyI32(long A, const iq10 &B) +{ + iq10 C; + C.val = (A * B.val); + return(C); +} + +inline iq9 +IQ9mpyI32(const iq9 &A, long B) +{ + iq9 C; + C.val = (A.val * B); + return(C); +} + +inline iq9 +IQ9mpyI32(long A, const iq9 &B) +{ + iq9 C; + C.val = (A * B.val); + return(C); +} + +inline iq8 +IQ8mpyI32(const iq8 &A, long B) +{ + iq8 C; + C.val = (A.val * B); + return(C); +} + +inline iq8 +IQ8mpyI32(long A, const iq8 &B) +{ + iq8 C; + C.val = (A * B.val); + return(C); +} + +inline iq7 +IQ7mpyI32(const iq7 &A, long B) +{ + iq7 C; + C.val = (A.val * B); + return(C); +} + +inline iq7 +IQ7mpyI32(long A, const iq7 &B) +{ + iq7 C; + C.val = (A * B.val); + return(C); +} + +inline iq6 +IQ6mpyI32(const iq6 &A, long B) +{ + iq6 C; + C.val = (A.val * B); + return(C); +} + +inline iq6 +IQ6mpyI32(long A, const iq6 &B) +{ + iq6 C; + C.val = (A * B.val); + return(C); +} + +inline iq5 +IQ5mpyI32(const iq5 &A, long B) +{ + iq5 C; + C.val = (A.val * B); + return(C); +} + +inline iq5 +IQ5mpyI32(long A, const iq5 &B) +{ + iq5 C; + C.val = (A * B.val); + return(C); +} + +inline iq4 +IQ4mpyI32(const iq4 &A, long B) +{ + iq4 C; + C.val = (A.val * B); + return(C); +} + +inline iq4 +IQ4mpyI32(long A, const iq4 &B) +{ + iq4 C; + C.val = (A * B.val); + return(C); +} + +inline iq3 +IQ3mpyI32(const iq3 &A, long B) +{ + iq3 C; + C.val = (A.val * B); + return(C); +} + +inline iq3 +IQ3mpyI32(long A, const iq3 &B) +{ + iq3 C; + C.val = (A * B.val); + return(C); +} + +inline iq2 +IQ2mpyI32(const iq2 &A, long B) +{ + iq2 C; + C.val = (A.val * B); + return(C); +} + +inline iq2 +IQ2mpyI32(long A, const iq2 &B) +{ + iq2 C; + C.val = (A * B.val); + return(C); +} + +inline iq1 +IQ1mpyI32(const iq1 &A, long B) +{ + iq1 C; + C.val = (A.val * B); + return(C); +} + +inline iq1 +IQ1mpyI32(long A, const iq1 &B) +{ + iq1 C; + C.val = (A * B.val); + return(C); +} + +inline iq +IQmpyI32(const iq &A, long B) +{ + iq C; + C.val = (A.val * B); + return(C); +} + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the integer portion. +// +//***************************************************************************** +inline long +IQ30mpyI32int(const iq30 &A, long B) +{ + return(_IQ30mpyI32int(A.val, B)); +} + +inline long +IQ30mpyI32int(long A, const iq30 &B) +{ + return(_IQ30mpyI32int(B.val, A)); +} + +inline long +IQ29mpyI32int(const iq29 &A, long B) +{ + return(_IQ29mpyI32int(A.val, B)); +} + +inline long +IQ29mpyI32int(long A, const iq29 &B) +{ + return(_IQ29mpyI32int(B.val, A)); +} + +inline long +IQ28mpyI32int(const iq28 &A, long B) +{ + return(_IQ28mpyI32int(A.val, B)); +} + +inline long +IQ28mpyI32int(long A, const iq28 &B) +{ + return(_IQ28mpyI32int(B.val, A)); +} + +inline long +IQ27mpyI32int(const iq27 &A, long B) +{ + return(_IQ27mpyI32int(A.val, B)); +} + +inline long +IQ27mpyI32int(long A, const iq27 &B) +{ + return(_IQ27mpyI32int(B.val, A)); +} + +inline long +IQ26mpyI32int(const iq26 &A, long B) +{ + return(_IQ26mpyI32int(A.val, B)); +} + +inline long +IQ26mpyI32int(long A, const iq26 &B) +{ + return(_IQ26mpyI32int(B.val, A)); +} + +inline long +IQ25mpyI32int(const iq25 &A, long B) +{ + return(_IQ25mpyI32int(A.val, B)); +} + +inline long +IQ25mpyI32int(long A, const iq25 &B) +{ + return(_IQ25mpyI32int(B.val, A)); +} + +inline long +IQ24mpyI32int(const iq24 &A, long B) +{ + return(_IQ24mpyI32int(A.val, B)); +} + +inline long +IQ24mpyI32int(long A, const iq24 &B) +{ + return(_IQ24mpyI32int(B.val, A)); +} + +inline long +IQ23mpyI32int(const iq23 &A, long B) +{ + return(_IQ23mpyI32int(A.val, B)); +} + +inline long +IQ23mpyI32int(long A, const iq23 &B) +{ + return(_IQ23mpyI32int(B.val, A)); +} + +inline long +IQ22mpyI32int(const iq22 &A, long B) +{ + return(_IQ22mpyI32int(A.val, B)); +} + +inline long +IQ22mpyI32int(long A, const iq22 &B) +{ + return(_IQ22mpyI32int(B.val, A)); +} + +inline long +IQ21mpyI32int(const iq21 &A, long B) +{ + return(_IQ21mpyI32int(A.val, B)); +} + +inline long +IQ21mpyI32int(long A, const iq21 &B) +{ + return(_IQ21mpyI32int(B.val, A)); +} + +inline long +IQ20mpyI32int(const iq20 &A, long B) +{ + return(_IQ20mpyI32int(A.val, B)); +} + +inline long +IQ20mpyI32int(long A, const iq20 &B) +{ + return(_IQ20mpyI32int(B.val, A)); +} + +inline long +IQ19mpyI32int(const iq19 &A, long B) +{ + return(_IQ19mpyI32int(A.val, B)); +} + +inline long +IQ19mpyI32int(long A, const iq19 &B) +{ + return(_IQ19mpyI32int(B.val, A)); +} + +inline long +IQ18mpyI32int(const iq18 &A, long B) +{ + return(_IQ18mpyI32int(A.val, B)); +} + +inline long +IQ18mpyI32int(long A, const iq18 &B) +{ + return(_IQ18mpyI32int(B.val, A)); +} + +inline long +IQ17mpyI32int(const iq17 &A, long B) +{ + return(_IQ17mpyI32int(A.val, B)); +} + +inline long +IQ17mpyI32int(long A, const iq17 &B) +{ + return(_IQ17mpyI32int(B.val, A)); +} + +inline long +IQ16mpyI32int(const iq16 &A, long B) +{ + return(_IQ16mpyI32int(A.val, B)); +} + +inline long +IQ16mpyI32int(long A, const iq16 &B) +{ + return(_IQ16mpyI32int(B.val, A)); +} + +inline long +IQ15mpyI32int(const iq15 &A, long B) +{ + return(_IQ15mpyI32int(A.val, B)); +} + +inline long +IQ15mpyI32int(long A, const iq15 &B) +{ + return(_IQ15mpyI32int(B.val, A)); +} + +inline long +IQ14mpyI32int(const iq14 &A, long B) +{ + return(_IQ14mpyI32int(A.val, B)); +} + +inline long +IQ14mpyI32int(long A, const iq14 &B) +{ + return(_IQ14mpyI32int(B.val, A)); +} + +inline long +IQ13mpyI32int(const iq13 &A, long B) +{ + return(_IQ13mpyI32int(A.val, B)); +} + +inline long +IQ13mpyI32int(long A, const iq13 &B) +{ + return(_IQ13mpyI32int(B.val, A)); +} + +inline long +IQ12mpyI32int(const iq12 &A, long B) +{ + return(_IQ12mpyI32int(A.val, B)); +} + +inline long +IQ12mpyI32int(long A, const iq12 &B) +{ + return(_IQ12mpyI32int(B.val, A)); +} + +inline long +IQ11mpyI32int(const iq11 &A, long B) +{ + return(_IQ11mpyI32int(A.val, B)); +} + +inline long +IQ11mpyI32int(long A, const iq11 &B) +{ + return(_IQ11mpyI32int(B.val, A)); +} + +inline long +IQ10mpyI32int(const iq10 &A, long B) +{ + return(_IQ10mpyI32int(A.val, B)); +} + +inline long +IQ10mpyI32int(long A, const iq10 &B) +{ + return(_IQ10mpyI32int(B.val, A)); +} + +inline long +IQ9mpyI32int(const iq9 &A, long B) +{ + return(_IQ9mpyI32int(A.val, B)); +} + +inline long +IQ9mpyI32int(long A, const iq9 &B) +{ + return(_IQ9mpyI32int(B.val, A)); +} + +inline long +IQ8mpyI32int(const iq8 &A, long B) +{ + return(_IQ8mpyI32int(A.val, B)); +} + +inline long +IQ8mpyI32int(long A, const iq8 &B) +{ + return(_IQ8mpyI32int(B.val, A)); +} + +inline long +IQ7mpyI32int(const iq7 &A, long B) +{ + return(_IQ7mpyI32int(A.val, B)); +} + +inline long +IQ7mpyI32int(long A, const iq7 &B) +{ + return(_IQ7mpyI32int(B.val, A)); +} + +inline long +IQ6mpyI32int(const iq6 &A, long B) +{ + return(_IQ6mpyI32int(A.val, B)); +} + +inline long +IQ6mpyI32int(long A, const iq6 &B) +{ + return(_IQ6mpyI32int(B.val, A)); +} + +inline long +IQ5mpyI32int(const iq5 &A, long B) +{ + return(_IQ5mpyI32int(A.val, B)); +} + +inline long +IQ5mpyI32int(long A, const iq5 &B) +{ + return(_IQ5mpyI32int(B.val, A)); +} + +inline long +IQ4mpyI32int(const iq4 &A, long B) +{ + return(_IQ4mpyI32int(A.val, B)); +} + +inline long +IQ4mpyI32int(long A, const iq4 &B) +{ + return(_IQ4mpyI32int(B.val, A)); +} + +inline long +IQ3mpyI32int(const iq3 &A, long B) +{ + return(_IQ3mpyI32int(A.val, B)); +} + +inline long +IQ3mpyI32int(long A, const iq3 &B) +{ + return(_IQ3mpyI32int(B.val, A)); +} + +inline long +IQ2mpyI32int(const iq2 &A, long B) +{ + return(_IQ2mpyI32int(A.val, B)); +} + +inline long +IQ2mpyI32int(long A, const iq2 &B) +{ + return(_IQ2mpyI32int(B.val, A)); +} + +inline long +IQ1mpyI32int(const iq1 &A, long B) +{ + return(_IQ1mpyI32int(A.val, B)); +} + +inline long +IQ1mpyI32int(long A, const iq1 &B) +{ + return(_IQ1mpyI32int(B.val, A)); +} + +inline long +IQmpyI32int(const iq &A, long B) +{ + return(_IQmpyI32int(A.val, B)); +} + +inline long +IQmpyI32int(long A, const iq &B) +{ + return(_IQmpyI32int(B.val, A)); +} + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the fractional portion. +// +//***************************************************************************** +inline iq30 +IQ30mpyI32frac(const iq30 &A, long B) +{ + iq30 C; + C.val = _IQ30mpyI32frac(A.val, B); + return(C); +} + +inline iq30 +IQ30mpyI32frac(long A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30mpyI32frac(B.val, A); + return(C); +} + + +inline iq29 +IQ29mpyI32frac(const iq29 &A, long B) +{ + iq29 C; + C.val = _IQ29mpyI32frac(A.val, B); + return(C); +} + +inline iq29 +IQ29mpyI32frac(long A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29mpyI32frac(B.val, A); + return(C); +} + + +inline iq28 +IQ28mpyI32frac(const iq28 &A, long B) +{ + iq28 C; + C.val = _IQ28mpyI32frac(A.val, B); + return(C); +} + +inline iq28 +IQ28mpyI32frac(long A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28mpyI32frac(B.val, A); + return(C); +} + + +inline iq27 +IQ27mpyI32frac(const iq27 &A, long B) +{ + iq27 C; + C.val = _IQ27mpyI32frac(A.val, B); + return(C); +} + +inline iq27 +IQ27mpyI32frac(long A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27mpyI32frac(B.val, A); + return(C); +} + + +inline iq26 +IQ26mpyI32frac(const iq26 &A, long B) +{ + iq26 C; + C.val = _IQ26mpyI32frac(A.val, B); + return(C); +} + +inline iq26 +IQ26mpyI32frac(long A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26mpyI32frac(B.val, A); + return(C); +} + + +inline iq25 +IQ25mpyI32frac(const iq25 &A, long B) +{ + iq25 C; + C.val = _IQ25mpyI32frac(A.val, B); + return(C); +} + +inline iq25 +IQ25mpyI32frac(long A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25mpyI32frac(B.val, A); + return(C); +} + + +inline iq24 +IQ24mpyI32frac(const iq24 &A, long B) +{ + iq24 C; + C.val = _IQ24mpyI32frac(A.val, B); + return(C); +} + +inline iq24 +IQ24mpyI32frac(long A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24mpyI32frac(B.val, A); + return(C); +} + + +inline iq23 +IQ23mpyI32frac(const iq23 &A, long B) +{ + iq23 C; + C.val = _IQ23mpyI32frac(A.val, B); + return(C); +} + +inline iq23 +IQ23mpyI32frac(long A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23mpyI32frac(B.val, A); + return(C); +} + + +inline iq22 +IQ22mpyI32frac(const iq22 &A, long B) +{ + iq22 C; + C.val = _IQ22mpyI32frac(A.val, B); + return(C); +} + +inline iq22 +IQ22mpyI32frac(long A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22mpyI32frac(B.val, A); + return(C); +} + + +inline iq21 +IQ21mpyI32frac(const iq21 &A, long B) +{ + iq21 C; + C.val = _IQ21mpyI32frac(A.val, B); + return(C); +} + +inline iq21 +IQ21mpyI32frac(long A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21mpyI32frac(B.val, A); + return(C); +} + + +inline iq20 +IQ20mpyI32frac(const iq20 &A, long B) +{ + iq20 C; + C.val = _IQ20mpyI32frac(A.val, B); + return(C); +} + +inline iq20 +IQ20mpyI32frac(long A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20mpyI32frac(B.val, A); + return(C); +} + + +inline iq19 +IQ19mpyI32frac(const iq19 &A, long B) +{ + iq19 C; + C.val = _IQ19mpyI32frac(A.val, B); + return(C); +} + +inline iq19 +IQ19mpyI32frac(long A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19mpyI32frac(B.val, A); + return(C); +} + + +inline iq18 +IQ18mpyI32frac(const iq18 &A, long B) +{ + iq18 C; + C.val = _IQ18mpyI32frac(A.val, B); + return(C); +} + +inline iq18 +IQ18mpyI32frac(long A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18mpyI32frac(B.val, A); + return(C); +} + + +inline iq17 +IQ17mpyI32frac(const iq17 &A, long B) +{ + iq17 C; + C.val = _IQ17mpyI32frac(A.val, B); + return(C); +} + +inline iq17 +IQ17mpyI32frac(long A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17mpyI32frac(B.val, A); + return(C); +} + + +inline iq16 +IQ16mpyI32frac(const iq16 &A, long B) +{ + iq16 C; + C.val = _IQ16mpyI32frac(A.val, B); + return(C); +} + +inline iq16 +IQ16mpyI32frac(long A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16mpyI32frac(B.val, A); + return(C); +} + + +inline iq15 +IQ15mpyI32frac(const iq15 &A, long B) +{ + iq15 C; + C.val = _IQ15mpyI32frac(A.val, B); + return(C); +} + +inline iq15 +IQ15mpyI32frac(long A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15mpyI32frac(B.val, A); + return(C); +} + + +inline iq14 +IQ14mpyI32frac(const iq14 &A, long B) +{ + iq14 C; + C.val = _IQ14mpyI32frac(A.val, B); + return(C); +} + +inline iq14 +IQ14mpyI32frac(long A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14mpyI32frac(B.val, A); + return(C); +} + + +inline iq13 +IQ13mpyI32frac(const iq13 &A, long B) +{ + iq13 C; + C.val = _IQ13mpyI32frac(A.val, B); + return(C); +} + +inline iq13 +IQ13mpyI32frac(long A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13mpyI32frac(B.val, A); + return(C); +} + + +inline iq12 +IQ12mpyI32frac(const iq12 &A, long B) +{ + iq12 C; + C.val = _IQ12mpyI32frac(A.val, B); + return(C); +} + +inline iq12 +IQ12mpyI32frac(long A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12mpyI32frac(B.val, A); + return(C); +} + + +inline iq11 +IQ11mpyI32frac(const iq11 &A, long B) +{ + iq11 C; + C.val = _IQ11mpyI32frac(A.val, B); + return(C); +} + +inline iq11 +IQ11mpyI32frac(long A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11mpyI32frac(B.val, A); + return(C); +} + + +inline iq10 +IQ10mpyI32frac(const iq10 &A, long B) +{ + iq10 C; + C.val = _IQ10mpyI32frac(A.val, B); + return(C); +} + +inline iq10 +IQ10mpyI32frac(long A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10mpyI32frac(B.val, A); + return(C); +} + + +inline iq9 +IQ9mpyI32frac(const iq9 &A, long B) +{ + iq9 C; + C.val = _IQ9mpyI32frac(A.val, B); + return(C); +} + +inline iq9 +IQ9mpyI32frac(long A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9mpyI32frac(B.val, A); + return(C); +} + + +inline iq8 +IQ8mpyI32frac(const iq8 &A, long B) +{ + iq8 C; + C.val = _IQ8mpyI32frac(A.val, B); + return(C); +} + +inline iq8 +IQ8mpyI32frac(long A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8mpyI32frac(B.val, A); + return(C); +} + + +inline iq7 +IQ7mpyI32frac(const iq7 &A, long B) +{ + iq7 C; + C.val = _IQ7mpyI32frac(A.val, B); + return(C); +} + +inline iq7 +IQ7mpyI32frac(long A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7mpyI32frac(B.val, A); + return(C); +} + + +inline iq6 +IQ6mpyI32frac(const iq6 &A, long B) +{ + iq6 C; + C.val = _IQ6mpyI32frac(A.val, B); + return(C); +} + +inline iq6 +IQ6mpyI32frac(long A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6mpyI32frac(B.val, A); + return(C); +} + + +inline iq5 +IQ5mpyI32frac(const iq5 &A, long B) +{ + iq5 C; + C.val = _IQ5mpyI32frac(A.val, B); + return(C); +} + +inline iq5 +IQ5mpyI32frac(long A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5mpyI32frac(B.val, A); + return(C); +} + + +inline iq4 +IQ4mpyI32frac(const iq4 &A, long B) +{ + iq4 C; + C.val = _IQ4mpyI32frac(A.val, B); + return(C); +} + +inline iq4 +IQ4mpyI32frac(long A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4mpyI32frac(B.val, A); + return(C); +} + + +inline iq3 +IQ3mpyI32frac(const iq3 &A, long B) +{ + iq3 C; + C.val = _IQ3mpyI32frac(A.val, B); + return(C); +} + +inline iq3 +IQ3mpyI32frac(long A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3mpyI32frac(B.val, A); + return(C); +} + + +inline iq2 +IQ2mpyI32frac(const iq2 &A, long B) +{ + iq2 C; + C.val = _IQ2mpyI32frac(A.val, B); + return(C); +} + +inline iq2 +IQ2mpyI32frac(long A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2mpyI32frac(B.val, A); + return(C); +} + + +inline iq1 +IQ1mpyI32frac(const iq1 &A, long B) +{ + iq1 C; + C.val = _IQ1mpyI32frac(A.val, B); + return(C); +} + +inline iq1 +IQ1mpyI32frac(long A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1mpyI32frac(B.val, A); + return(C); +} + + +inline iq +IQmpyI32frac(const iq &A, long B) +{ + iq C; + C.val = _IQmpyI32frac(A.val, B); + return(C); +} + +inline iq +IQmpyI32frac(long A, const iq &B) +{ + iq C; + C.val = _IQmpyI32frac(B.val, A); + return(C); +} + +//***************************************************************************** +// +// Computes the sin of an IQ number. +// +//***************************************************************************** +inline iq29 +IQ29sin(const iq29 &A) +{ + iq29 B; + B.val = _IQ29sin(A.val); + return(B); +} + +inline iq28 +IQ28sin(const iq28 &A) +{ + iq28 B; + B.val = _IQ28sin(A.val); + return(B); +} + +inline iq27 +IQ27sin(const iq27 &A) +{ + iq27 B; + B.val = _IQ27sin(A.val); + return(B); +} + +inline iq26 +IQ26sin(const iq26 &A) +{ + iq26 B; + B.val = _IQ26sin(A.val); + return(B); +} + +inline iq25 +IQ25sin(const iq25 &A) +{ + iq25 B; + B.val = _IQ25sin(A.val); + return(B); +} + +inline iq24 +IQ24sin(const iq24 &A) +{ + iq24 B; + B.val = _IQ24sin(A.val); + return(B); +} + +inline iq23 +IQ23sin(const iq23 &A) +{ + iq23 B; + B.val = _IQ23sin(A.val); + return(B); +} + +inline iq22 +IQ22sin(const iq22 &A) +{ + iq22 B; + B.val = _IQ22sin(A.val); + return(B); +} + +inline iq21 +IQ21sin(const iq21 &A) +{ + iq21 B; + B.val = _IQ21sin(A.val); + return(B); +} + +inline iq20 +IQ20sin(const iq20 &A) +{ + iq20 B; + B.val = _IQ20sin(A.val); + return(B); +} + +inline iq19 +IQ19sin(const iq19 &A) +{ + iq19 B; + B.val = _IQ19sin(A.val); + return(B); +} + +inline iq18 +IQ18sin(const iq18 &A) +{ + iq18 B; + B.val = _IQ18sin(A.val); + return(B); +} + +inline iq17 +IQ17sin(const iq17 &A) +{ + iq17 B; + B.val = _IQ17sin(A.val); + return(B); +} + +inline iq16 +IQ16sin(const iq16 &A) +{ + iq16 B; + B.val = _IQ16sin(A.val); + return(B); +} + +inline iq15 +IQ15sin(const iq15 &A) +{ + iq15 B; + B.val = _IQ15sin(A.val); + return(B); +} + +inline iq14 +IQ14sin(const iq14 &A) +{ + iq14 B; + B.val = _IQ14sin(A.val); + return(B); +} + +inline iq13 +IQ13sin(const iq13 &A) +{ + iq13 B; + B.val = _IQ13sin(A.val); + return(B); +} + +inline iq12 +IQ12sin(const iq12 &A) +{ + iq12 B; + B.val = _IQ12sin(A.val); + return(B); +} + +inline iq11 +IQ11sin(const iq11 &A) +{ + iq11 B; + B.val = _IQ11sin(A.val); + return(B); +} + +inline iq10 +IQ10sin(const iq10 &A) +{ + iq10 B; + B.val = _IQ10sin(A.val); + return(B); +} + +inline iq9 +IQ9sin(const iq9 &A) +{ + iq9 B; + B.val = _IQ9sin(A.val); + return(B); +} + +inline iq8 +IQ8sin(const iq8 &A) +{ + iq8 B; + B.val = _IQ8sin(A.val); + return(B); +} + +inline iq7 +IQ7sin(const iq7 &A) +{ + iq7 B; + B.val = _IQ7sin(A.val); + return(B); +} + +inline iq6 +IQ6sin(const iq6 &A) +{ + iq6 B; + B.val = _IQ6sin(A.val); + return(B); +} + +inline iq5 +IQ5sin(const iq5 &A) +{ + iq5 B; + B.val = _IQ5sin(A.val); + return(B); +} + +inline iq4 +IQ4sin(const iq4 &A) +{ + iq4 B; + B.val = _IQ4sin(A.val); + return(B); +} + +inline iq3 +IQ3sin(const iq3 &A) +{ + iq3 B; + B.val = _IQ3sin(A.val); + return(B); +} + +inline iq2 +IQ2sin(const iq2 &A) +{ + iq2 B; + B.val = _IQ2sin(A.val); + return(B); +} + +inline iq1 +IQ1sin(const iq1 &A) +{ + iq1 B; + B.val = _IQ1sin(A.val); + return(B); +} + +inline iq +IQsin(const iq &A) +{ + iq B; + B.val = _IQsin(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the sin of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +inline iq30 +IQ30sinPU(const iq30 &A) +{ + iq30 B; + B.val = _IQ30sinPU(A.val); + return(B); +} + +inline iq29 +IQ29sinPU(const iq29 &A) +{ + iq29 B; + B.val = _IQ29sinPU(A.val); + return(B); +} + +inline iq28 +IQ28sinPU(const iq28 &A) +{ + iq28 B; + B.val = _IQ28sinPU(A.val); + return(B); +} + +inline iq27 +IQ27sinPU(const iq27 &A) +{ + iq27 B; + B.val = _IQ27sinPU(A.val); + return(B); +} + +inline iq26 +IQ26sinPU(const iq26 &A) +{ + iq26 B; + B.val = _IQ26sinPU(A.val); + return(B); +} + +inline iq25 +IQ25sinPU(const iq25 &A) +{ + iq25 B; + B.val = _IQ25sinPU(A.val); + return(B); +} + +inline iq24 +IQ24sinPU(const iq24 &A) +{ + iq24 B; + B.val = _IQ24sinPU(A.val); + return(B); +} + +inline iq23 +IQ23sinPU(const iq23 &A) +{ + iq23 B; + B.val = _IQ23sinPU(A.val); + return(B); +} + +inline iq22 +IQ22sinPU(const iq22 &A) +{ + iq22 B; + B.val = _IQ22sinPU(A.val); + return(B); +} + +inline iq21 +IQ21sinPU(const iq21 &A) +{ + iq21 B; + B.val = _IQ21sinPU(A.val); + return(B); +} + +inline iq20 +IQ20sinPU(const iq20 &A) +{ + iq20 B; + B.val = _IQ20sinPU(A.val); + return(B); +} + +inline iq19 +IQ19sinPU(const iq19 &A) +{ + iq19 B; + B.val = _IQ19sinPU(A.val); + return(B); +} + +inline iq18 +IQ18sinPU(const iq18 &A) +{ + iq18 B; + B.val = _IQ18sinPU(A.val); + return(B); +} + +inline iq17 +IQ17sinPU(const iq17 &A) +{ + iq17 B; + B.val = _IQ17sinPU(A.val); + return(B); +} + +inline iq16 +IQ16sinPU(const iq16 &A) +{ + iq16 B; + B.val = _IQ16sinPU(A.val); + return(B); +} + +inline iq15 +IQ15sinPU(const iq15 &A) +{ + iq15 B; + B.val = _IQ15sinPU(A.val); + return(B); +} + +inline iq14 +IQ14sinPU(const iq14 &A) +{ + iq14 B; + B.val = _IQ14sinPU(A.val); + return(B); +} + +inline iq13 +IQ13sinPU(const iq13 &A) +{ + iq13 B; + B.val = _IQ13sinPU(A.val); + return(B); +} + +inline iq12 +IQ12sinPU(const iq12 &A) +{ + iq12 B; + B.val = _IQ12sinPU(A.val); + return(B); +} + +inline iq11 +IQ11sinPU(const iq11 &A) +{ + iq11 B; + B.val = _IQ11sinPU(A.val); + return(B); +} + +inline iq10 +IQ10sinPU(const iq10 &A) +{ + iq10 B; + B.val = _IQ10sinPU(A.val); + return(B); +} + +inline iq9 +IQ9sinPU(const iq9 &A) +{ + iq9 B; + B.val = _IQ9sinPU(A.val); + return(B); +} + +inline iq8 +IQ8sinPU(const iq8 &A) +{ + iq8 B; + B.val = _IQ8sinPU(A.val); + return(B); +} + +inline iq7 +IQ7sinPU(const iq7 &A) +{ + iq7 B; + B.val = _IQ7sinPU(A.val); + return(B); +} + +inline iq6 +IQ6sinPU(const iq6 &A) +{ + iq6 B; + B.val = _IQ6sinPU(A.val); + return(B); +} + +inline iq5 +IQ5sinPU(const iq5 &A) +{ + iq5 B; + B.val = _IQ5sinPU(A.val); + return(B); +} + +inline iq4 +IQ4sinPU(const iq4 &A) +{ + iq4 B; + B.val = _IQ4sinPU(A.val); + return(B); +} + +inline iq3 +IQ3sinPU(const iq3 &A) +{ + iq3 B; + B.val = _IQ3sinPU(A.val); + return(B); +} + +inline iq2 +IQ2sinPU(const iq2 &A) +{ + iq2 B; + B.val = _IQ2sinPU(A.val); + return(B); +} + +inline iq1 +IQ1sinPU(const iq1 &A) +{ + iq1 B; + B.val = _IQ1sinPU(A.val); + return(B); +} + +inline iq +IQsinPU(const iq &A) +{ + iq B; + B.val = _IQsinPU(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the arcsin of an IQ number. +// +//***************************************************************************** +inline iq29 +IQ29asin(const iq29 &A) +{ + iq29 B; + B.val = _IQ29asin(A.val); + return(B); +} + +inline iq28 +IQ28asin(const iq28 &A) +{ + iq28 B; + B.val = _IQ28asin(A.val); + return(B); +} + +inline iq27 +IQ27asin(const iq27 &A) +{ + iq27 B; + B.val = _IQ27asin(A.val); + return(B); +} + +inline iq26 +IQ26asin(const iq26 &A) +{ + iq26 B; + B.val = _IQ26asin(A.val); + return(B); +} + +inline iq25 +IQ25asin(const iq25 &A) +{ + iq25 B; + B.val = _IQ25asin(A.val); + return(B); +} + +inline iq24 +IQ24asin(const iq24 &A) +{ + iq24 B; + B.val = _IQ24asin(A.val); + return(B); +} + +inline iq23 +IQ23asin(const iq23 &A) +{ + iq23 B; + B.val = _IQ23asin(A.val); + return(B); +} + +inline iq22 +IQ22asin(const iq22 &A) +{ + iq22 B; + B.val = _IQ22asin(A.val); + return(B); +} + +inline iq21 +IQ21asin(const iq21 &A) +{ + iq21 B; + B.val = _IQ21asin(A.val); + return(B); +} + +inline iq20 +IQ20asin(const iq20 &A) +{ + iq20 B; + B.val = _IQ20asin(A.val); + return(B); +} + +inline iq19 +IQ19asin(const iq19 &A) +{ + iq19 B; + B.val = _IQ19asin(A.val); + return(B); +} + +inline iq18 +IQ18asin(const iq18 &A) +{ + iq18 B; + B.val = _IQ18asin(A.val); + return(B); +} + +inline iq17 +IQ17asin(const iq17 &A) +{ + iq17 B; + B.val = _IQ17asin(A.val); + return(B); +} + +inline iq16 +IQ16asin(const iq16 &A) +{ + iq16 B; + B.val = _IQ16asin(A.val); + return(B); +} + +inline iq15 +IQ15asin(const iq15 &A) +{ + iq15 B; + B.val = _IQ15asin(A.val); + return(B); +} + +inline iq14 +IQ14asin(const iq14 &A) +{ + iq14 B; + B.val = _IQ14asin(A.val); + return(B); +} + +inline iq13 +IQ13asin(const iq13 &A) +{ + iq13 B; + B.val = _IQ13asin(A.val); + return(B); +} + +inline iq12 +IQ12asin(const iq12 &A) +{ + iq12 B; + B.val = _IQ12asin(A.val); + return(B); +} + +inline iq11 +IQ11asin(const iq11 &A) +{ + iq11 B; + B.val = _IQ11asin(A.val); + return(B); +} + +inline iq10 +IQ10asin(const iq10 &A) +{ + iq10 B; + B.val = _IQ10asin(A.val); + return(B); +} + +inline iq9 +IQ9asin(const iq9 &A) +{ + iq9 B; + B.val = _IQ9asin(A.val); + return(B); +} + +inline iq8 +IQ8asin(const iq8 &A) +{ + iq8 B; + B.val = _IQ8asin(A.val); + return(B); +} + +inline iq7 +IQ7asin(const iq7 &A) +{ + iq7 B; + B.val = _IQ7asin(A.val); + return(B); +} + +inline iq6 +IQ6asin(const iq6 &A) +{ + iq6 B; + B.val = _IQ6asin(A.val); + return(B); +} + +inline iq5 +IQ5asin(const iq5 &A) +{ + iq5 B; + B.val = _IQ5asin(A.val); + return(B); +} + +inline iq4 +IQ4asin(const iq4 &A) +{ + iq4 B; + B.val = _IQ4asin(A.val); + return(B); +} + +inline iq3 +IQ3asin(const iq3 &A) +{ + iq3 B; + B.val = _IQ3asin(A.val); + return(B); +} + +inline iq2 +IQ2asin(const iq2 &A) +{ + iq2 B; + B.val = _IQ2asin(A.val); + return(B); +} + +inline iq1 +IQ1asin(const iq1 &A) +{ + iq1 B; + B.val = _IQ1asin(A.val); + return(B); +} + +inline iq +IQasin(const iq &A) +{ + iq B; + B.val = _IQasin(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the cos of an IQ number. +// +//***************************************************************************** +inline iq29 +IQ29cos(const iq29 &A) +{ + iq29 B; + B.val = _IQ29cos(A.val); + return(B); +} + +inline iq28 +IQ28cos(const iq28 &A) +{ + iq28 B; + B.val = _IQ28cos(A.val); + return(B); +} + +inline iq27 +IQ27cos(const iq27 &A) +{ + iq27 B; + B.val = _IQ27cos(A.val); + return(B); +} + +inline iq26 +IQ26cos(const iq26 &A) +{ + iq26 B; + B.val = _IQ26cos(A.val); + return(B); +} + +inline iq25 +IQ25cos(const iq25 &A) +{ + iq25 B; + B.val = _IQ25cos(A.val); + return(B); +} + +inline iq24 +IQ24cos(const iq24 &A) +{ + iq24 B; + B.val = _IQ24cos(A.val); + return(B); +} + +inline iq23 +IQ23cos(const iq23 &A) +{ + iq23 B; + B.val = _IQ23cos(A.val); + return(B); +} + +inline iq22 +IQ22cos(const iq22 &A) +{ + iq22 B; + B.val = _IQ22cos(A.val); + return(B); +} + +inline iq21 +IQ21cos(const iq21 &A) +{ + iq21 B; + B.val = _IQ21cos(A.val); + return(B); +} + +inline iq20 +IQ20cos(const iq20 &A) +{ + iq20 B; + B.val = _IQ20cos(A.val); + return(B); +} + +inline iq19 +IQ19cos(const iq19 &A) +{ + iq19 B; + B.val = _IQ19cos(A.val); + return(B); +} + +inline iq18 +IQ18cos(const iq18 &A) +{ + iq18 B; + B.val = _IQ18cos(A.val); + return(B); +} + +inline iq17 +IQ17cos(const iq17 &A) +{ + iq17 B; + B.val = _IQ17cos(A.val); + return(B); +} + +inline iq16 +IQ16cos(const iq16 &A) +{ + iq16 B; + B.val = _IQ16cos(A.val); + return(B); +} + +inline iq15 +IQ15cos(const iq15 &A) +{ + iq15 B; + B.val = _IQ15cos(A.val); + return(B); +} + +inline iq14 +IQ14cos(const iq14 &A) +{ + iq14 B; + B.val = _IQ14cos(A.val); + return(B); +} + +inline iq13 +IQ13cos(const iq13 &A) +{ + iq13 B; + B.val = _IQ13cos(A.val); + return(B); +} + +inline iq12 +IQ12cos(const iq12 &A) +{ + iq12 B; + B.val = _IQ12cos(A.val); + return(B); +} + +inline iq11 +IQ11cos(const iq11 &A) +{ + iq11 B; + B.val = _IQ11cos(A.val); + return(B); +} + +inline iq10 +IQ10cos(const iq10 &A) +{ + iq10 B; + B.val = _IQ10cos(A.val); + return(B); +} + +inline iq9 +IQ9cos(const iq9 &A) +{ + iq9 B; + B.val = _IQ9cos(A.val); + return(B); +} + +inline iq8 +IQ8cos(const iq8 &A) +{ + iq8 B; + B.val = _IQ8cos(A.val); + return(B); +} + +inline iq7 +IQ7cos(const iq7 &A) +{ + iq7 B; + B.val = _IQ7cos(A.val); + return(B); +} + +inline iq6 +IQ6cos(const iq6 &A) +{ + iq6 B; + B.val = _IQ6cos(A.val); + return(B); +} + +inline iq5 +IQ5cos(const iq5 &A) +{ + iq5 B; + B.val = _IQ5cos(A.val); + return(B); +} + +inline iq4 +IQ4cos(const iq4 &A) +{ + iq4 B; + B.val = _IQ4cos(A.val); + return(B); +} + +inline iq3 +IQ3cos(const iq3 &A) +{ + iq3 B; + B.val = _IQ3cos(A.val); + return(B); +} + +inline iq2 +IQ2cos(const iq2 &A) +{ + iq2 B; + B.val = _IQ2cos(A.val); + return(B); +} + +inline iq1 +IQ1cos(const iq1 &A) +{ + iq1 B; + B.val = _IQ1cos(A.val); + return(B); +} + +inline iq +IQcos(const iq &A) +{ + iq B; + B.val = _IQcos(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the cos of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +inline iq30 +IQ30cosPU(const iq30 &A) +{ + iq30 B; + B.val = _IQ30cosPU(A.val); + return(B); +} + +inline iq29 +IQ29cosPU(const iq29 &A) +{ + iq29 B; + B.val = _IQ29cosPU(A.val); + return(B); +} + +inline iq28 +IQ28cosPU(const iq28 &A) +{ + iq28 B; + B.val = _IQ28cosPU(A.val); + return(B); +} + +inline iq27 +IQ27cosPU(const iq27 &A) +{ + iq27 B; + B.val = _IQ27cosPU(A.val); + return(B); +} + +inline iq26 +IQ26cosPU(const iq26 &A) +{ + iq26 B; + B.val = _IQ26cosPU(A.val); + return(B); +} + +inline iq25 +IQ25cosPU(const iq25 &A) +{ + iq25 B; + B.val = _IQ25cosPU(A.val); + return(B); +} + +inline iq24 +IQ24cosPU(const iq24 &A) +{ + iq24 B; + B.val = _IQ24cosPU(A.val); + return(B); +} + +inline iq23 +IQ23cosPU(const iq23 &A) +{ + iq23 B; + B.val = _IQ23cosPU(A.val); + return(B); +} + +inline iq22 +IQ22cosPU(const iq22 &A) +{ + iq22 B; + B.val = _IQ22cosPU(A.val); + return(B); +} + +inline iq21 +IQ21cosPU(const iq21 &A) +{ + iq21 B; + B.val = _IQ21cosPU(A.val); + return(B); +} + +inline iq20 +IQ20cosPU(const iq20 &A) +{ + iq20 B; + B.val = _IQ20cosPU(A.val); + return(B); +} + +inline iq19 +IQ19cosPU(const iq19 &A) +{ + iq19 B; + B.val = _IQ19cosPU(A.val); + return(B); +} + +inline iq18 +IQ18cosPU(const iq18 &A) +{ + iq18 B; + B.val = _IQ18cosPU(A.val); + return(B); +} + +inline iq17 +IQ17cosPU(const iq17 &A) +{ + iq17 B; + B.val = _IQ17cosPU(A.val); + return(B); +} + +inline iq16 +IQ16cosPU(const iq16 &A) +{ + iq16 B; + B.val = _IQ16cosPU(A.val); + return(B); +} + +inline iq15 +IQ15cosPU(const iq15 &A) +{ + iq15 B; + B.val = _IQ15cosPU(A.val); + return(B); +} + +inline iq14 +IQ14cosPU(const iq14 &A) +{ + iq14 B; + B.val = _IQ14cosPU(A.val); + return(B); +} + +inline iq13 +IQ13cosPU(const iq13 &A) +{ + iq13 B; + B.val = _IQ13cosPU(A.val); + return(B); +} + +inline iq12 +IQ12cosPU(const iq12 &A) +{ + iq12 B; + B.val = _IQ12cosPU(A.val); + return(B); +} + +inline iq11 +IQ11cosPU(const iq11 &A) +{ + iq11 B; + B.val = _IQ11cosPU(A.val); + return(B); +} + +inline iq10 +IQ10cosPU(const iq10 &A) +{ + iq10 B; + B.val = _IQ10cosPU(A.val); + return(B); +} + +inline iq9 +IQ9cosPU(const iq9 &A) +{ + iq9 B; + B.val = _IQ9cosPU(A.val); + return(B); +} + +inline iq8 +IQ8cosPU(const iq8 &A) +{ + iq8 B; + B.val = _IQ8cosPU(A.val); + return(B); +} + +inline iq7 +IQ7cosPU(const iq7 &A) +{ + iq7 B; + B.val = _IQ7cosPU(A.val); + return(B); +} + +inline iq6 +IQ6cosPU(const iq6 &A) +{ + iq6 B; + B.val = _IQ6cosPU(A.val); + return(B); +} + +inline iq5 +IQ5cosPU(const iq5 &A) +{ + iq5 B; + B.val = _IQ5cosPU(A.val); + return(B); +} + +inline iq4 +IQ4cosPU(const iq4 &A) +{ + iq4 B; + B.val = _IQ4cosPU(A.val); + return(B); +} + +inline iq3 +IQ3cosPU(const iq3 &A) +{ + iq3 B; + B.val = _IQ3cosPU(A.val); + return(B); +} + +inline iq2 +IQ2cosPU(const iq2 &A) +{ + iq2 B; + B.val = _IQ2cosPU(A.val); + return(B); +} + +inline iq1 +IQ1cosPU(const iq1 &A) +{ + iq1 B; + B.val = _IQ1cosPU(A.val); + return(B); +} + +inline iq +IQcosPU(const iq &A) +{ + iq B; + B.val = _IQcosPU(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the arccos of an IQ number. +// +//***************************************************************************** +inline iq29 +IQ29acos(const iq29 &A) +{ + iq29 B; + B.val = _IQ29acos(A.val); + return(B); +} + +inline iq28 +IQ28acos(const iq28 &A) +{ + iq28 B; + B.val = _IQ28acos(A.val); + return(B); +} + +inline iq27 +IQ27acos(const iq27 &A) +{ + iq27 B; + B.val = _IQ27acos(A.val); + return(B); +} + +inline iq26 +IQ26acos(const iq26 &A) +{ + iq26 B; + B.val = _IQ26acos(A.val); + return(B); +} + +inline iq25 +IQ25acos(const iq25 &A) +{ + iq25 B; + B.val = _IQ25acos(A.val); + return(B); +} + +inline iq24 +IQ24acos(const iq24 &A) +{ + iq24 B; + B.val = _IQ24acos(A.val); + return(B); +} + +inline iq23 +IQ23acos(const iq23 &A) +{ + iq23 B; + B.val = _IQ23acos(A.val); + return(B); +} + +inline iq22 +IQ22acos(const iq22 &A) +{ + iq22 B; + B.val = _IQ22acos(A.val); + return(B); +} + +inline iq21 +IQ21acos(const iq21 &A) +{ + iq21 B; + B.val = _IQ21acos(A.val); + return(B); +} + +inline iq20 +IQ20acos(const iq20 &A) +{ + iq20 B; + B.val = _IQ20acos(A.val); + return(B); +} + +inline iq19 +IQ19acos(const iq19 &A) +{ + iq19 B; + B.val = _IQ19acos(A.val); + return(B); +} + +inline iq18 +IQ18acos(const iq18 &A) +{ + iq18 B; + B.val = _IQ18acos(A.val); + return(B); +} + +inline iq17 +IQ17acos(const iq17 &A) +{ + iq17 B; + B.val = _IQ17acos(A.val); + return(B); +} + +inline iq16 +IQ16acos(const iq16 &A) +{ + iq16 B; + B.val = _IQ16acos(A.val); + return(B); +} + +inline iq15 +IQ15acos(const iq15 &A) +{ + iq15 B; + B.val = _IQ15acos(A.val); + return(B); +} + +inline iq14 +IQ14acos(const iq14 &A) +{ + iq14 B; + B.val = _IQ14acos(A.val); + return(B); +} + +inline iq13 +IQ13acos(const iq13 &A) +{ + iq13 B; + B.val = _IQ13acos(A.val); + return(B); +} + +inline iq12 +IQ12acos(const iq12 &A) +{ + iq12 B; + B.val = _IQ12acos(A.val); + return(B); +} + +inline iq11 +IQ11acos(const iq11 &A) +{ + iq11 B; + B.val = _IQ11acos(A.val); + return(B); +} + +inline iq10 +IQ10acos(const iq10 &A) +{ + iq10 B; + B.val = _IQ10acos(A.val); + return(B); +} + +inline iq9 +IQ9acos(const iq9 &A) +{ + iq9 B; + B.val = _IQ9acos(A.val); + return(B); +} + +inline iq8 +IQ8acos(const iq8 &A) +{ + iq8 B; + B.val = _IQ8acos(A.val); + return(B); +} + +inline iq7 +IQ7acos(const iq7 &A) +{ + iq7 B; + B.val = _IQ7acos(A.val); + return(B); +} + +inline iq6 +IQ6acos(const iq6 &A) +{ + iq6 B; + B.val = _IQ6acos(A.val); + return(B); +} + +inline iq5 +IQ5acos(const iq5 &A) +{ + iq5 B; + B.val = _IQ5acos(A.val); + return(B); +} + +inline iq4 +IQ4acos(const iq4 &A) +{ + iq4 B; + B.val = _IQ4acos(A.val); + return(B); +} + +inline iq3 +IQ3acos(const iq3 &A) +{ + iq3 B; + B.val = _IQ3acos(A.val); + return(B); +} + +inline iq2 +IQ2acos(const iq2 &A) +{ + iq2 B; + B.val = _IQ2acos(A.val); + return(B); +} + +inline iq1 +IQ1acos(const iq1 &A) +{ + iq1 B; + B.val = _IQ1acos(A.val); + return(B); +} + +inline iq +IQacos(const iq &A) +{ + iq B; + B.val = _IQacos(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers. +// +//***************************************************************************** +inline iq29 +IQ29atan2(const iq29 &A, iq29 &B) +{ + iq29 C; + C.val = _IQ29atan2(A.val, B.val); + return(C); +} + +inline iq28 +IQ28atan2(const iq28 &A, iq28 &B) +{ + iq28 C; + C.val = _IQ28atan2(A.val, B.val); + return(C); +} + +inline iq27 +IQ27atan2(const iq27 &A, iq27 &B) +{ + iq27 C; + C.val = _IQ27atan2(A.val, B.val); + return(C); +} + +inline iq26 +IQ26atan2(const iq26 &A, iq26 &B) +{ + iq26 C; + C.val = _IQ26atan2(A.val, B.val); + return(C); +} + +inline iq25 +IQ25atan2(const iq25 &A, iq25 &B) +{ + iq25 C; + C.val = _IQ25atan2(A.val, B.val); + return(C); +} + +inline iq24 +IQ24atan2(const iq24 &A, iq24 &B) +{ + iq24 C; + C.val = _IQ24atan2(A.val, B.val); + return(C); +} + +inline iq23 +IQ23atan2(const iq23 &A, iq23 &B) +{ + iq23 C; + C.val = _IQ23atan2(A.val, B.val); + return(C); +} + +inline iq22 +IQ22atan2(const iq22 &A, iq22 &B) +{ + iq22 C; + C.val = _IQ22atan2(A.val, B.val); + return(C); +} + +inline iq21 +IQ21atan2(const iq21 &A, iq21 &B) +{ + iq21 C; + C.val = _IQ21atan2(A.val, B.val); + return(C); +} + +inline iq20 +IQ20atan2(const iq20 &A, iq20 &B) +{ + iq20 C; + C.val = _IQ20atan2(A.val, B.val); + return(C); +} + +inline iq19 +IQ19atan2(const iq19 &A, iq19 &B) +{ + iq19 C; + C.val = _IQ19atan2(A.val, B.val); + return(C); +} + +inline iq18 +IQ18atan2(const iq18 &A, iq18 &B) +{ + iq18 C; + C.val = _IQ18atan2(A.val, B.val); + return(C); +} + +inline iq17 +IQ17atan2(const iq17 &A, iq17 &B) +{ + iq17 C; + C.val = _IQ17atan2(A.val, B.val); + return(C); +} + +inline iq16 +IQ16atan2(const iq16 &A, iq16 &B) +{ + iq16 C; + C.val = _IQ16atan2(A.val, B.val); + return(C); +} + +inline iq15 +IQ15atan2(const iq15 &A, iq15 &B) +{ + iq15 C; + C.val = _IQ15atan2(A.val, B.val); + return(C); +} + +inline iq14 +IQ14atan2(const iq14 &A, iq14 &B) +{ + iq14 C; + C.val = _IQ14atan2(A.val, B.val); + return(C); +} + +inline iq13 +IQ13atan2(const iq13 &A, iq13 &B) +{ + iq13 C; + C.val = _IQ13atan2(A.val, B.val); + return(C); +} + +inline iq12 +IQ12atan2(const iq12 &A, iq12 &B) +{ + iq12 C; + C.val = _IQ12atan2(A.val, B.val); + return(C); +} + +inline iq11 +IQ11atan2(const iq11 &A, iq11 &B) +{ + iq11 C; + C.val = _IQ11atan2(A.val, B.val); + return(C); +} + +inline iq10 +IQ10atan2(const iq10 &A, iq10 &B) +{ + iq10 C; + C.val = _IQ10atan2(A.val, B.val); + return(C); +} + +inline iq9 +IQ9atan2(const iq9 &A, iq9 &B) +{ + iq9 C; + C.val = _IQ9atan2(A.val, B.val); + return(C); +} + +inline iq8 +IQ8atan2(const iq8 &A, iq8 &B) +{ + iq8 C; + C.val = _IQ8atan2(A.val, B.val); + return(C); +} + +inline iq7 +IQ7atan2(const iq7 &A, iq7 &B) +{ + iq7 C; + C.val = _IQ7atan2(A.val, B.val); + return(C); +} + +inline iq6 +IQ6atan2(const iq6 &A, iq6 &B) +{ + iq6 C; + C.val = _IQ6atan2(A.val, B.val); + return(C); +} + +inline iq5 +IQ5atan2(const iq5 &A, iq5 &B) +{ + iq5 C; + C.val = _IQ5atan2(A.val, B.val); + return(C); +} + +inline iq4 +IQ4atan2(const iq4 &A, iq4 &B) +{ + iq4 C; + C.val = _IQ4atan2(A.val, B.val); + return(C); +} + +inline iq3 +IQ3atan2(const iq3 &A, iq3 &B) +{ + iq3 C; + C.val = _IQ3atan2(A.val, B.val); + return(C); +} + +inline iq2 +IQ2atan2(const iq2 &A, iq2 &B) +{ + iq2 C; + C.val = _IQ2atan2(A.val, B.val); + return(C); +} + +inline iq1 +IQ1atan2(const iq1 &A, iq1 &B) +{ + iq1 C; + C.val = _IQ1atan2(A.val, B.val); + return(C); +} + +inline iq +IQatan2(const iq &A, iq &B) +{ + iq C; + C.val = _IQatan2(A.val, B.val); + return(C); +} + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers, returning +// the value in cycles per unit instead of radians. +// +//***************************************************************************** +inline iq30 +IQ30atan2PU(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30atan2PU(A.val, B.val); + return(C); +} + +inline iq29 +IQ29atan2PU(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29atan2PU(A.val, B.val); + return(C); +} + +inline iq28 +IQ28atan2PU(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28atan2PU(A.val, B.val); + return(C); +} + +inline iq27 +IQ27atan2PU(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27atan2PU(A.val, B.val); + return(C); +} + +inline iq26 +IQ26atan2PU(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26atan2PU(A.val, B.val); + return(C); +} + +inline iq25 +IQ25atan2PU(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25atan2PU(A.val, B.val); + return(C); +} + +inline iq24 +IQ24atan2PU(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24atan2PU(A.val, B.val); + return(C); +} + +inline iq23 +IQ23atan2PU(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23atan2PU(A.val, B.val); + return(C); +} + +inline iq22 +IQ22atan2PU(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22atan2PU(A.val, B.val); + return(C); +} + +inline iq21 +IQ21atan2PU(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21atan2PU(A.val, B.val); + return(C); +} + +inline iq20 +IQ20atan2PU(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20atan2PU(A.val, B.val); + return(C); +} + +inline iq19 +IQ19atan2PU(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19atan2PU(A.val, B.val); + return(C); +} + +inline iq18 +IQ18atan2PU(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18atan2PU(A.val, B.val); + return(C); +} + +inline iq17 +IQ17atan2PU(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17atan2PU(A.val, B.val); + return(C); +} + +inline iq16 +IQ16atan2PU(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16atan2PU(A.val, B.val); + return(C); +} + +inline iq15 +IQ15atan2PU(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15atan2PU(A.val, B.val); + return(C); +} + +inline iq14 +IQ14atan2PU(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14atan2PU(A.val, B.val); + return(C); +} + +inline iq13 +IQ13atan2PU(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13atan2PU(A.val, B.val); + return(C); +} + +inline iq12 +IQ12atan2PU(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12atan2PU(A.val, B.val); + return(C); +} + +inline iq11 +IQ11atan2PU(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11atan2PU(A.val, B.val); + return(C); +} + +inline iq10 +IQ10atan2PU(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10atan2PU(A.val, B.val); + return(C); +} + +inline iq9 +IQ9atan2PU(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9atan2PU(A.val, B.val); + return(C); +} + +inline iq8 +IQ8atan2PU(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8atan2PU(A.val, B.val); + return(C); +} + +inline iq7 +IQ7atan2PU(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7atan2PU(A.val, B.val); + return(C); +} + +inline iq6 +IQ6atan2PU(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6atan2PU(A.val, B.val); + return(C); +} + +inline iq5 +IQ5atan2PU(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5atan2PU(A.val, B.val); + return(C); +} + +inline iq4 +IQ4atan2PU(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4atan2PU(A.val, B.val); + return(C); +} + +inline iq3 +IQ3atan2PU(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3atan2PU(A.val, B.val); + return(C); +} + +inline iq2 +IQ2atan2PU(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2atan2PU(A.val, B.val); + return(C); +} + +inline iq1 +IQ1atan2PU(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1atan2PU(A.val, B.val); + return(C); +} + +inline iq +IQatan2PU(const iq &A, const iq &B) +{ + iq C; + C.val = _IQatan2PU(A.val, B.val); + return(C); +} + +//***************************************************************************** +// +// Computes the arctan of an IQ number. +// +//***************************************************************************** +#define IQ29atan(A) IQ29atan2(A, IQ29(1.0)) +#define IQ28atan(A) IQ28atan2(A, IQ28(1.0)) +#define IQ27atan(A) IQ27atan2(A, IQ27(1.0)) +#define IQ26atan(A) IQ26atan2(A, IQ26(1.0)) +#define IQ25atan(A) IQ25atan2(A, IQ25(1.0)) +#define IQ24atan(A) IQ24atan2(A, IQ24(1.0)) +#define IQ23atan(A) IQ23atan2(A, IQ23(1.0)) +#define IQ22atan(A) IQ22atan2(A, IQ22(1.0)) +#define IQ21atan(A) IQ21atan2(A, IQ21(1.0)) +#define IQ20atan(A) IQ20atan2(A, IQ20(1.0)) +#define IQ19atan(A) IQ19atan2(A, IQ19(1.0)) +#define IQ18atan(A) IQ18atan2(A, IQ18(1.0)) +#define IQ17atan(A) IQ17atan2(A, IQ17(1.0)) +#define IQ16atan(A) IQ16atan2(A, IQ16(1.0)) +#define IQ15atan(A) IQ15atan2(A, IQ15(1.0)) +#define IQ14atan(A) IQ14atan2(A, IQ14(1.0)) +#define IQ13atan(A) IQ13atan2(A, IQ13(1.0)) +#define IQ12atan(A) IQ12atan2(A, IQ12(1.0)) +#define IQ11atan(A) IQ11atan2(A, IQ11(1.0)) +#define IQ10atan(A) IQ10atan2(A, IQ10(1.0)) +#define IQ9atan(A) IQ9atan2(A, IQ9(1.0)) +#define IQ8atan(A) IQ8atan2(A, IQ8(1.0)) +#define IQ7atan(A) IQ7atan2(A, IQ7(1.0)) +#define IQ6atan(A) IQ6atan2(A, IQ6(1.0)) +#define IQ5atan(A) IQ5atan2(A, IQ5(1.0)) +#define IQ4atan(A) IQ4atan2(A, IQ4(1.0)) +#define IQ3atan(A) IQ3atan2(A, IQ3(1.0)) +#define IQ2atan(A) IQ2atan2(A, IQ2(1.0)) +#define IQ1atan(A) IQ1atan2(A, IQ1(1.0)) +#define IQatan(A) IQatan2(A, IQ(1.0)) + +//***************************************************************************** +// +// Computes the square root of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30sqrt(const iq30 &A) +{ + iq30 B; + B.val = _IQ30sqrt(A.val); + return(B); +} + +inline iq29 +IQ29sqrt(const iq29 &A) +{ + iq29 B; + B.val = _IQ29sqrt(A.val); + return(B); +} + +inline iq28 +IQ28sqrt(const iq28 &A) +{ + iq28 B; + B.val = _IQ28sqrt(A.val); + return(B); +} + +inline iq27 +IQ27sqrt(const iq27 &A) +{ + iq27 B; + B.val = _IQ27sqrt(A.val); + return(B); +} + +inline iq26 +IQ26sqrt(const iq26 &A) +{ + iq26 B; + B.val = _IQ26sqrt(A.val); + return(B); +} + +inline iq25 +IQ25sqrt(const iq25 &A) +{ + iq25 B; + B.val = _IQ25sqrt(A.val); + return(B); +} + +inline iq24 +IQ24sqrt(const iq24 &A) +{ + iq24 B; + B.val = _IQ24sqrt(A.val); + return(B); +} + +inline iq23 +IQ23sqrt(const iq23 &A) +{ + iq23 B; + B.val = _IQ23sqrt(A.val); + return(B); +} + +inline iq22 +IQ22sqrt(const iq22 &A) +{ + iq22 B; + B.val = _IQ22sqrt(A.val); + return(B); +} + +inline iq21 +IQ21sqrt(const iq21 &A) +{ + iq21 B; + B.val = _IQ21sqrt(A.val); + return(B); +} + +inline iq20 +IQ20sqrt(const iq20 &A) +{ + iq20 B; + B.val = _IQ20sqrt(A.val); + return(B); +} + +inline iq19 +IQ19sqrt(const iq19 &A) +{ + iq19 B; + B.val = _IQ19sqrt(A.val); + return(B); +} + +inline iq18 +IQ18sqrt(const iq18 &A) +{ + iq18 B; + B.val = _IQ18sqrt(A.val); + return(B); +} + +inline iq17 +IQ17sqrt(const iq17 &A) +{ + iq17 B; + B.val = _IQ17sqrt(A.val); + return(B); +} + +inline iq16 +IQ16sqrt(const iq16 &A) +{ + iq16 B; + B.val = _IQ16sqrt(A.val); + return(B); +} + +inline iq15 +IQ15sqrt(const iq15 &A) +{ + iq15 B; + B.val = _IQ15sqrt(A.val); + return(B); +} + +inline iq14 +IQ14sqrt(const iq14 &A) +{ + iq14 B; + B.val = _IQ14sqrt(A.val); + return(B); +} + +inline iq13 +IQ13sqrt(const iq13 &A) +{ + iq13 B; + B.val = _IQ13sqrt(A.val); + return(B); +} + +inline iq12 +IQ12sqrt(const iq12 &A) +{ + iq12 B; + B.val = _IQ12sqrt(A.val); + return(B); +} + +inline iq11 +IQ11sqrt(const iq11 &A) +{ + iq11 B; + B.val = _IQ11sqrt(A.val); + return(B); +} + +inline iq10 +IQ10sqrt(const iq10 &A) +{ + iq10 B; + B.val = _IQ10sqrt(A.val); + return(B); +} + +inline iq9 +IQ9sqrt(const iq9 &A) +{ + iq9 B; + B.val = _IQ9sqrt(A.val); + return(B); +} + +inline iq8 +IQ8sqrt(const iq8 &A) +{ + iq8 B; + B.val = _IQ8sqrt(A.val); + return(B); +} + +inline iq7 +IQ7sqrt(const iq7 &A) +{ + iq7 B; + B.val = _IQ7sqrt(A.val); + return(B); +} + +inline iq6 +IQ6sqrt(const iq6 &A) +{ + iq6 B; + B.val = _IQ6sqrt(A.val); + return(B); +} + +inline iq5 +IQ5sqrt(const iq5 &A) +{ + iq5 B; + B.val = _IQ5sqrt(A.val); + return(B); +} + +inline iq4 +IQ4sqrt(const iq4 &A) +{ + iq4 B; + B.val = _IQ4sqrt(A.val); + return(B); +} + +inline iq3 +IQ3sqrt(const iq3 &A) +{ + iq3 B; + B.val = _IQ3sqrt(A.val); + return(B); +} + +inline iq2 +IQ2sqrt(const iq2 &A) +{ + iq2 B; + B.val = _IQ2sqrt(A.val); + return(B); +} + +inline iq1 +IQ1sqrt(const iq1 &A) +{ + iq1 B; + B.val = _IQ1sqrt(A.val); + return(B); +} + +inline iq +IQsqrt(const iq &A) +{ + iq B; + B.val = _IQsqrt(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes 1 over the square root of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30isqrt(const iq30 &A) +{ + iq30 B; + B.val = _IQ30isqrt(A.val); + return(B); +} + +inline iq29 +IQ29isqrt(const iq29 &A) +{ + iq29 B; + B.val = _IQ29isqrt(A.val); + return(B); +} + +inline iq28 +IQ28isqrt(const iq28 &A) +{ + iq28 B; + B.val = _IQ28isqrt(A.val); + return(B); +} + +inline iq27 +IQ27isqrt(const iq27 &A) +{ + iq27 B; + B.val = _IQ27isqrt(A.val); + return(B); +} + +inline iq26 +IQ26isqrt(const iq26 &A) +{ + iq26 B; + B.val = _IQ26isqrt(A.val); + return(B); +} + +inline iq25 +IQ25isqrt(const iq25 &A) +{ + iq25 B; + B.val = _IQ25isqrt(A.val); + return(B); +} + +inline iq24 +IQ24isqrt(const iq24 &A) +{ + iq24 B; + B.val = _IQ24isqrt(A.val); + return(B); +} + +inline iq23 +IQ23isqrt(const iq23 &A) +{ + iq23 B; + B.val = _IQ23isqrt(A.val); + return(B); +} + +inline iq22 +IQ22isqrt(const iq22 &A) +{ + iq22 B; + B.val = _IQ22isqrt(A.val); + return(B); +} + +inline iq21 +IQ21isqrt(const iq21 &A) +{ + iq21 B; + B.val = _IQ21isqrt(A.val); + return(B); +} + +inline iq20 +IQ20isqrt(const iq20 &A) +{ + iq20 B; + B.val = _IQ20isqrt(A.val); + return(B); +} + +inline iq19 +IQ19isqrt(const iq19 &A) +{ + iq19 B; + B.val = _IQ19isqrt(A.val); + return(B); +} + +inline iq18 +IQ18isqrt(const iq18 &A) +{ + iq18 B; + B.val = _IQ18isqrt(A.val); + return(B); +} + +inline iq17 +IQ17isqrt(const iq17 &A) +{ + iq17 B; + B.val = _IQ17isqrt(A.val); + return(B); +} + +inline iq16 +IQ16isqrt(const iq16 &A) +{ + iq16 B; + B.val = _IQ16isqrt(A.val); + return(B); +} + +inline iq15 +IQ15isqrt(const iq15 &A) +{ + iq15 B; + B.val = _IQ15isqrt(A.val); + return(B); +} + +inline iq14 +IQ14isqrt(const iq14 &A) +{ + iq14 B; + B.val = _IQ14isqrt(A.val); + return(B); +} + +inline iq13 +IQ13isqrt(const iq13 &A) +{ + iq13 B; + B.val = _IQ13isqrt(A.val); + return(B); +} + +inline iq12 +IQ12isqrt(const iq12 &A) +{ + iq12 B; + B.val = _IQ12isqrt(A.val); + return(B); +} + +inline iq11 +IQ11isqrt(const iq11 &A) +{ + iq11 B; + B.val = _IQ11isqrt(A.val); + return(B); +} + +inline iq10 +IQ10isqrt(const iq10 &A) +{ + iq10 B; + B.val = _IQ10isqrt(A.val); + return(B); +} + +inline iq9 +IQ9isqrt(const iq9 &A) +{ + iq9 B; + B.val = _IQ9isqrt(A.val); + return(B); +} + +inline iq8 +IQ8isqrt(const iq8 &A) +{ + iq8 B; + B.val = _IQ8isqrt(A.val); + return(B); +} + +inline iq7 +IQ7isqrt(const iq7 &A) +{ + iq7 B; + B.val = _IQ7isqrt(A.val); + return(B); +} + +inline iq6 +IQ6isqrt(const iq6 &A) +{ + iq6 B; + B.val = _IQ6isqrt(A.val); + return(B); +} + +inline iq5 +IQ5isqrt(const iq5 &A) +{ + iq5 B; + B.val = _IQ5isqrt(A.val); + return(B); +} + +inline iq4 +IQ4isqrt(const iq4 &A) +{ + iq4 B; + B.val = _IQ4isqrt(A.val); + return(B); +} + +inline iq3 +IQ3isqrt(const iq3 &A) +{ + iq3 B; + B.val = _IQ3isqrt(A.val); + return(B); +} + +inline iq2 +IQ2isqrt(const iq2 &A) +{ + iq2 B; + B.val = _IQ2isqrt(A.val); + return(B); +} + +inline iq1 +IQ1isqrt(const iq1 &A) +{ + iq1 B; + B.val = _IQ1isqrt(A.val); + return(B); +} + +inline iq +IQisqrt(const iq &A) +{ + iq B; + B.val = _IQisqrt(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes e^x of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30exp(const iq30 &A) +{ + iq30 B; + B.val = _IQ30exp(A.val); + return(B); +} + +inline iq29 +IQ29exp(const iq29 &A) +{ + iq29 B; + B.val = _IQ29exp(A.val); + return(B); +} + +inline iq28 +IQ28exp(const iq28 &A) +{ + iq28 B; + B.val = _IQ28exp(A.val); + return(B); +} + +inline iq27 +IQ27exp(const iq27 &A) +{ + iq27 B; + B.val = _IQ27exp(A.val); + return(B); +} + +inline iq26 +IQ26exp(const iq26 &A) +{ + iq26 B; + B.val = _IQ26exp(A.val); + return(B); +} + +inline iq25 +IQ25exp(const iq25 &A) +{ + iq25 B; + B.val = _IQ25exp(A.val); + return(B); +} + +inline iq24 +IQ24exp(const iq24 &A) +{ + iq24 B; + B.val = _IQ24exp(A.val); + return(B); +} + +inline iq23 +IQ23exp(const iq23 &A) +{ + iq23 B; + B.val = _IQ23exp(A.val); + return(B); +} + +inline iq22 +IQ22exp(const iq22 &A) +{ + iq22 B; + B.val = _IQ22exp(A.val); + return(B); +} + +inline iq21 +IQ21exp(const iq21 &A) +{ + iq21 B; + B.val = _IQ21exp(A.val); + return(B); +} + +inline iq20 +IQ20exp(const iq20 &A) +{ + iq20 B; + B.val = _IQ20exp(A.val); + return(B); +} + +inline iq19 +IQ19exp(const iq19 &A) +{ + iq19 B; + B.val = _IQ19exp(A.val); + return(B); +} + +inline iq18 +IQ18exp(const iq18 &A) +{ + iq18 B; + B.val = _IQ18exp(A.val); + return(B); +} + +inline iq17 +IQ17exp(const iq17 &A) +{ + iq17 B; + B.val = _IQ17exp(A.val); + return(B); +} + +inline iq16 +IQ16exp(const iq16 &A) +{ + iq16 B; + B.val = _IQ16exp(A.val); + return(B); +} + +inline iq15 +IQ15exp(const iq15 &A) +{ + iq15 B; + B.val = _IQ15exp(A.val); + return(B); +} + +inline iq14 +IQ14exp(const iq14 &A) +{ + iq14 B; + B.val = _IQ14exp(A.val); + return(B); +} + +inline iq13 +IQ13exp(const iq13 &A) +{ + iq13 B; + B.val = _IQ13exp(A.val); + return(B); +} + +inline iq12 +IQ12exp(const iq12 &A) +{ + iq12 B; + B.val = _IQ12exp(A.val); + return(B); +} + +inline iq11 +IQ11exp(const iq11 &A) +{ + iq11 B; + B.val = _IQ11exp(A.val); + return(B); +} + +inline iq10 +IQ10exp(const iq10 &A) +{ + iq10 B; + B.val = _IQ10exp(A.val); + return(B); +} + +inline iq9 +IQ9exp(const iq9 &A) +{ + iq9 B; + B.val = _IQ9exp(A.val); + return(B); +} + +inline iq8 +IQ8exp(const iq8 &A) +{ + iq8 B; + B.val = _IQ8exp(A.val); + return(B); +} + +inline iq7 +IQ7exp(const iq7 &A) +{ + iq7 B; + B.val = _IQ7exp(A.val); + return(B); +} + +inline iq6 +IQ6exp(const iq6 &A) +{ + iq6 B; + B.val = _IQ6exp(A.val); + return(B); +} + +inline iq5 +IQ5exp(const iq5 &A) +{ + iq5 B; + B.val = _IQ5exp(A.val); + return(B); +} + +inline iq4 +IQ4exp(const iq4 &A) +{ + iq4 B; + B.val = _IQ4exp(A.val); + return(B); +} + +inline iq3 +IQ3exp(const iq3 &A) +{ + iq3 B; + B.val = _IQ3exp(A.val); + return(B); +} + +inline iq2 +IQ2exp(const iq2 &A) +{ + iq2 B; + B.val = _IQ2exp(A.val); + return(B); +} + +inline iq1 +IQ1exp(const iq1 &A) +{ + iq1 B; + B.val = _IQ1exp(A.val); + return(B); +} + +inline iq +IQexp(const iq &A) +{ + iq B; + B.val = _IQexp(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes 2^x of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30exp2(const iq30 &A) +{ + iq30 B; + B.val = _IQ30exp2(A.val); + return(B); +} + +inline iq29 +IQ29exp2(const iq29 &A) +{ + iq29 B; + B.val = _IQ29exp2(A.val); + return(B); +} + +inline iq28 +IQ28exp2(const iq28 &A) +{ + iq28 B; + B.val = _IQ28exp2(A.val); + return(B); +} + +inline iq27 +IQ27exp2(const iq27 &A) +{ + iq27 B; + B.val = _IQ27exp2(A.val); + return(B); +} + +inline iq26 +IQ26exp2(const iq26 &A) +{ + iq26 B; + B.val = _IQ26exp2(A.val); + return(B); +} + +inline iq25 +IQ25exp2(const iq25 &A) +{ + iq25 B; + B.val = _IQ25exp2(A.val); + return(B); +} + +inline iq24 +IQ24exp2(const iq24 &A) +{ + iq24 B; + B.val = _IQ24exp2(A.val); + return(B); +} + +inline iq23 +IQ23exp2(const iq23 &A) +{ + iq23 B; + B.val = _IQ23exp2(A.val); + return(B); +} + +inline iq22 +IQ22exp2(const iq22 &A) +{ + iq22 B; + B.val = _IQ22exp2(A.val); + return(B); +} + +inline iq21 +IQ21exp2(const iq21 &A) +{ + iq21 B; + B.val = _IQ21exp2(A.val); + return(B); +} + +inline iq20 +IQ20exp2(const iq20 &A) +{ + iq20 B; + B.val = _IQ20exp2(A.val); + return(B); +} + +inline iq19 +IQ19exp2(const iq19 &A) +{ + iq19 B; + B.val = _IQ19exp2(A.val); + return(B); +} + +inline iq18 +IQ18exp2(const iq18 &A) +{ + iq18 B; + B.val = _IQ18exp2(A.val); + return(B); +} + +inline iq17 +IQ17exp2(const iq17 &A) +{ + iq17 B; + B.val = _IQ17exp2(A.val); + return(B); +} + +inline iq16 +IQ16exp2(const iq16 &A) +{ + iq16 B; + B.val = _IQ16exp2(A.val); + return(B); +} + +inline iq15 +IQ15exp2(const iq15 &A) +{ + iq15 B; + B.val = _IQ15exp2(A.val); + return(B); +} + +inline iq14 +IQ14exp2(const iq14 &A) +{ + iq14 B; + B.val = _IQ14exp2(A.val); + return(B); +} + +inline iq13 +IQ13exp2(const iq13 &A) +{ + iq13 B; + B.val = _IQ13exp2(A.val); + return(B); +} + +inline iq12 +IQ12exp2(const iq12 &A) +{ + iq12 B; + B.val = _IQ12exp2(A.val); + return(B); +} + +inline iq11 +IQ11exp2(const iq11 &A) +{ + iq11 B; + B.val = _IQ11exp2(A.val); + return(B); +} + +inline iq10 +IQ10exp2(const iq10 &A) +{ + iq10 B; + B.val = _IQ10exp2(A.val); + return(B); +} + +inline iq9 +IQ9exp2(const iq9 &A) +{ + iq9 B; + B.val = _IQ9exp2(A.val); + return(B); +} + +inline iq8 +IQ8exp2(const iq8 &A) +{ + iq8 B; + B.val = _IQ8exp2(A.val); + return(B); +} + +inline iq7 +IQ7exp2(const iq7 &A) +{ + iq7 B; + B.val = _IQ7exp2(A.val); + return(B); +} + +inline iq6 +IQ6exp2(const iq6 &A) +{ + iq6 B; + B.val = _IQ6exp2(A.val); + return(B); +} + +inline iq5 +IQ5exp2(const iq5 &A) +{ + iq5 B; + B.val = _IQ5exp2(A.val); + return(B); +} + +inline iq4 +IQ4exp2(const iq4 &A) +{ + iq4 B; + B.val = _IQ4exp2(A.val); + return(B); +} + +inline iq3 +IQ3exp2(const iq3 &A) +{ + iq3 B; + B.val = _IQ3exp2(A.val); + return(B); +} + +inline iq2 +IQ2exp2(const iq2 &A) +{ + iq2 B; + B.val = _IQ2exp2(A.val); + return(B); +} + +inline iq1 +IQ1exp2(const iq1 &A) +{ + iq1 B; + B.val = _IQ1exp2(A.val); + return(B); +} + +inline iq +IQexp2(const iq &A) +{ + iq B; + B.val = _IQexp2(A.val); + return(B); +} + +//***************************************************************************** +// +// Computes the square root of A^2 + B^2 using IQ numbers. +// +//***************************************************************************** +inline iq30 +IQ30mag(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30mag(A.val, B.val); + return(C); +} + +inline iq29 +IQ29mag(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29mag(A.val, B.val); + return(C); +} + +inline iq28 +IQ28mag(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28mag(A.val, B.val); + return(C); +} + +inline iq27 +IQ27mag(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27mag(A.val, B.val); + return(C); +} + +inline iq26 +IQ26mag(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26mag(A.val, B.val); + return(C); +} + +inline iq25 +IQ25mag(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25mag(A.val, B.val); + return(C); +} + +inline iq24 +IQ24mag(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24mag(A.val, B.val); + return(C); +} + +inline iq23 +IQ23mag(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23mag(A.val, B.val); + return(C); +} + +inline iq22 +IQ22mag(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22mag(A.val, B.val); + return(C); +} + +inline iq21 +IQ21mag(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21mag(A.val, B.val); + return(C); +} + +inline iq20 +IQ20mag(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20mag(A.val, B.val); + return(C); +} + +inline iq19 +IQ19mag(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19mag(A.val, B.val); + return(C); +} + +inline iq18 +IQ18mag(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18mag(A.val, B.val); + return(C); +} + +inline iq17 +IQ17mag(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17mag(A.val, B.val); + return(C); +} + +inline iq16 +IQ16mag(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16mag(A.val, B.val); + return(C); +} + +inline iq15 +IQ15mag(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15mag(A.val, B.val); + return(C); +} + +inline iq14 +IQ14mag(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14mag(A.val, B.val); + return(C); +} + +inline iq13 +IQ13mag(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13mag(A.val, B.val); + return(C); +} + +inline iq12 +IQ12mag(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12mag(A.val, B.val); + return(C); +} + +inline iq11 +IQ11mag(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11mag(A.val, B.val); + return(C); +} + +inline iq10 +IQ10mag(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10mag(A.val, B.val); + return(C); +} + +inline iq9 +IQ9mag(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9mag(A.val, B.val); + return(C); +} + +inline iq8 +IQ8mag(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8mag(A.val, B.val); + return(C); +} + +inline iq7 +IQ7mag(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7mag(A.val, B.val); + return(C); +} + +inline iq6 +IQ6mag(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6mag(A.val, B.val); + return(C); +} + +inline iq5 +IQ5mag(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5mag(A.val, B.val); + return(C); +} + +inline iq4 +IQ4mag(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4mag(A.val, B.val); + return(C); +} + +inline iq3 +IQ3mag(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3mag(A.val, B.val); + return(C); +} + +inline iq2 +IQ2mag(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2mag(A.val, B.val); + return(C); +} + +inline iq1 +IQ1mag(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1mag(A.val, B.val); + return(C); +} + +inline iq +IQmag(const iq &A, const iq &B) +{ + iq C; + C.val = _IQmag(A.val, B.val); + return(C); +} + +//***************************************************************************** +// +// Computes the absolute value of an IQ number. +// +//***************************************************************************** +inline iq30 +IQ30abs(const iq30 &A) +{ + iq30 B; + B.val = _IQ30abs(A.val); + return(B); +} + +inline iq29 +IQ29abs(const iq29 &A) +{ + iq29 B; + B.val = _IQ29abs(A.val); + return(B); +} + +inline iq28 +IQ28abs(const iq28 &A) +{ + iq28 B; + B.val = _IQ28abs(A.val); + return(B); +} + +inline iq27 +IQ27abs(const iq27 &A) +{ + iq27 B; + B.val = _IQ27abs(A.val); + return(B); +} + +inline iq26 +IQ26abs(const iq26 &A) +{ + iq26 B; + B.val = _IQ26abs(A.val); + return(B); +} + +inline iq25 +IQ25abs(const iq25 &A) +{ + iq25 B; + B.val = _IQ25abs(A.val); + return(B); +} + +inline iq24 +IQ24abs(const iq24 &A) +{ + iq24 B; + B.val = _IQ24abs(A.val); + return(B); +} + +inline iq23 +IQ23abs(const iq23 &A) +{ + iq23 B; + B.val = _IQ23abs(A.val); + return(B); +} + +inline iq22 +IQ22abs(const iq22 &A) +{ + iq22 B; + B.val = _IQ22abs(A.val); + return(B); +} + +inline iq21 +IQ21abs(const iq21 &A) +{ + iq21 B; + B.val = _IQ21abs(A.val); + return(B); +} + +inline iq20 +IQ20abs(const iq20 &A) +{ + iq20 B; + B.val = _IQ20abs(A.val); + return(B); +} + +inline iq19 +IQ19abs(const iq19 &A) +{ + iq19 B; + B.val = _IQ19abs(A.val); + return(B); +} + +inline iq18 +IQ18abs(const iq18 &A) +{ + iq18 B; + B.val = _IQ18abs(A.val); + return(B); +} + +inline iq17 +IQ17abs(const iq17 &A) +{ + iq17 B; + B.val = _IQ17abs(A.val); + return(B); +} + +inline iq16 +IQ16abs(const iq16 &A) +{ + iq16 B; + B.val = _IQ16abs(A.val); + return(B); +} + +inline iq15 +IQ15abs(const iq15 &A) +{ + iq15 B; + B.val = _IQ15abs(A.val); + return(B); +} + +inline iq14 +IQ14abs(const iq14 &A) +{ + iq14 B; + B.val = _IQ14abs(A.val); + return(B); +} + +inline iq13 +IQ13abs(const iq13 &A) +{ + iq13 B; + B.val = _IQ13abs(A.val); + return(B); +} + +inline iq12 +IQ12abs(const iq12 &A) +{ + iq12 B; + B.val = _IQ12abs(A.val); + return(B); +} + +inline iq11 +IQ11abs(const iq11 &A) +{ + iq11 B; + B.val = _IQ11abs(A.val); + return(B); +} + +inline iq10 +IQ10abs(const iq10 &A) +{ + iq10 B; + B.val = _IQ10abs(A.val); + return(B); +} + +inline iq +IQabs(const iq &A) +{ + iq B; + B.val = _IQabs(A.val); + return(B); +} + +//***************************************************************************** +// +// Operator "=". +// +//***************************************************************************** +inline iq30 & +iq30::operator=(const iq30 &A) +{ + val = A.val; + return(*this); +} + +inline iq29 & +iq29::operator=(const iq29 &A) +{ + val = A.val; + return(*this); +} + +inline iq28 & +iq28::operator=(const iq28 &A) +{ + val = A.val; + return(*this); +} + +inline iq27 & +iq27::operator=(const iq27 &A) +{ + val = A.val; + return(*this); +} + +inline iq26 & +iq26::operator=(const iq26 &A) +{ + val = A.val; + return(*this); +} + +inline iq25 & +iq25::operator=(const iq25 &A) +{ + val = A.val; + return(*this); +} + +inline iq24 & +iq24::operator=(const iq24 &A) +{ + val = A.val; + return(*this); +} + +inline iq23 & +iq23::operator=(const iq23 &A) +{ + val = A.val; + return(*this); +} + +inline iq22 & +iq22::operator=(const iq22 &A) +{ + val = A.val; + return(*this); +} + +inline iq21 & +iq21::operator=(const iq21 &A) +{ + val = A.val; + return(*this); +} + +inline iq20 & +iq20::operator=(const iq20 &A) +{ + val = A.val; + return(*this); +} + +inline iq19 & +iq19::operator=(const iq19 &A) +{ + val = A.val; + return(*this); +} + +inline iq18 & +iq18::operator=(const iq18 &A) +{ + val = A.val; + return(*this); +} + +inline iq17 & +iq17::operator=(const iq17 &A) +{ + val = A.val; + return(*this); +} + +inline iq16 & +iq16::operator=(const iq16 &A) +{ + val = A.val; + return(*this); +} + +inline iq15 & +iq15::operator=(const iq15 &A) +{ + val = A.val; + return(*this); +} + +inline iq14 & +iq14::operator=(const iq14 &A) +{ + val = A.val; + return(*this); +} + +inline iq13 & +iq13::operator=(const iq13 &A) +{ + val = A.val; + return(*this); +} + +inline iq12 & +iq12::operator=(const iq12 &A) +{ + val = A.val; + return(*this); +} + +inline iq11 & +iq11::operator=(const iq11 &A) +{ + val = A.val; + return(*this); +} + +inline iq10 & +iq10::operator=(const iq10 &A) +{ + val = A.val; + return(*this); +} + +inline iq9 & +iq9::operator=(const iq9 &A) +{ + val = A.val; + return(*this); +} + +inline iq8 & +iq8::operator=(const iq8 &A) +{ + val = A.val; + return(*this); +} + +inline iq7 & +iq7::operator=(const iq7 &A) +{ + val = A.val; + return(*this); +} + +inline iq6 & +iq6::operator=(const iq6 &A) +{ + val = A.val; + return(*this); +} + +inline iq5 & +iq5::operator=(const iq5 &A) +{ + val = A.val; + return(*this); +} + +inline iq4 & +iq4::operator=(const iq4 &A) +{ + val = A.val; + return(*this); +} + +inline iq3 & +iq3::operator=(const iq3 &A) +{ + val = A.val; + return(*this); +} + +inline iq2 & +iq2::operator=(const iq2 &A) +{ + val = A.val; + return(*this); +} + +inline iq1 & +iq1::operator=(const iq1 &A) +{ + val = A.val; + return(*this); +} + +inline iq & +iq::operator=(const iq &A) +{ + val = A.val; + return(*this); +} + +//***************************************************************************** +// +// Operators "+" and "+=". +// +//***************************************************************************** +inline iq30 +operator+(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = A.val + B.val; + return(C); +} + +inline iq30 & +iq30::operator+=(const iq30 &A) +{ + val += A.val; + return(*this); +} + +inline iq29 +operator+(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = A.val + B.val; + return(C); +} + +inline iq29 & +iq29::operator+=(const iq29 &A) +{ + val += A.val; + return(*this); +} + +inline iq28 +operator+(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = A.val + B.val; + return(C); +} + +inline iq28 & +iq28::operator+=(const iq28 &A) +{ + val += A.val; + return(*this); +} + +inline iq27 +operator+(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = A.val + B.val; + return(C); +} + +inline iq27 & +iq27::operator+=(const iq27 &A) +{ + val += A.val; + return(*this); +} + +inline iq26 +operator+(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = A.val + B.val; + return(C); +} + +inline iq26 & +iq26::operator+=(const iq26 &A) +{ + val += A.val; + return(*this); +} + +inline iq25 +operator+(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = A.val + B.val; + return(C); +} + +inline iq25 & +iq25::operator+=(const iq25 &A) +{ + val += A.val; + return(*this); +} + +inline iq24 +operator+(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = A.val + B.val; + return(C); +} + +inline iq24 & +iq24::operator+=(const iq24 &A) +{ + val += A.val; + return(*this); +} + +inline iq23 +operator+(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = A.val + B.val; + return(C); +} + +inline iq23 & +iq23::operator+=(const iq23 &A) +{ + val += A.val; + return(*this); +} + +inline iq22 +operator+(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = A.val + B.val; + return(C); +} + +inline iq22 & +iq22::operator+=(const iq22 &A) +{ + val += A.val; + return(*this); +} + +inline iq21 +operator+(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = A.val + B.val; + return(C); +} + +inline iq21 & +iq21::operator+=(const iq21 &A) +{ + val += A.val; + return(*this); +} + +inline iq20 +operator+(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = A.val + B.val; + return(C); +} + +inline iq20 & +iq20::operator+=(const iq20 &A) +{ + val += A.val; + return(*this); +} + +inline iq19 +operator+(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = A.val + B.val; + return(C); +} + +inline iq19 & +iq19::operator+=(const iq19 &A) +{ + val += A.val; + return(*this); +} + +inline iq18 +operator+(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = A.val + B.val; + return(C); +} + +inline iq18 & +iq18::operator+=(const iq18 &A) +{ + val += A.val; + return(*this); +} + +inline iq17 +operator+(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = A.val + B.val; + return(C); +} + +inline iq17 & +iq17::operator+=(const iq17 &A) +{ + val += A.val; + return(*this); +} + +inline iq16 +operator+(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = A.val + B.val; + return(C); +} + +inline iq16 & +iq16::operator+=(const iq16 &A) +{ + val += A.val; + return(*this); +} + +inline iq15 +operator+(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = A.val + B.val; + return(C); +} + +inline iq15 & +iq15::operator+=(const iq15 &A) +{ + val += A.val; + return(*this); +} + +inline iq14 +operator+(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = A.val + B.val; + return(C); +} + +inline iq14 & +iq14::operator+=(const iq14 &A) +{ + val += A.val; + return(*this); +} + +inline iq13 +operator+(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = A.val + B.val; + return(C); +} + +inline iq13 & +iq13::operator+=(const iq13 &A) +{ + val += A.val; + return(*this); +} + +inline iq12 +operator+(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = A.val + B.val; + return(C); +} + +inline iq12 & +iq12::operator+=(const iq12 &A) +{ + val += A.val; + return(*this); +} + +inline iq11 +operator+(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = A.val + B.val; + return(C); +} + +inline iq11 & +iq11::operator+=(const iq11 &A) +{ + val += A.val; + return(*this); +} + +inline iq10 +operator+(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = A.val + B.val; + return(C); +} + +inline iq10 & +iq10::operator+=(const iq10 &A) +{ + val += A.val; + return(*this); +} + +inline iq9 +operator+(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = A.val + B.val; + return(C); +} + +inline iq9 & +iq9::operator+=(const iq9 &A) +{ + val += A.val; + return(*this); +} + +inline iq8 +operator+(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = A.val + B.val; + return(C); +} + +inline iq8 & +iq8::operator+=(const iq8 &A) +{ + val += A.val; + return(*this); +} + +inline iq7 +operator+(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = A.val + B.val; + return(C); +} + +inline iq7 & +iq7::operator+=(const iq7 &A) +{ + val += A.val; + return(*this); +} + +inline iq6 +operator+(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = A.val + B.val; + return(C); +} + +inline iq6 & +iq6::operator+=(const iq6 &A) +{ + val += A.val; + return(*this); +} + +inline iq5 +operator+(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = A.val + B.val; + return(C); +} + +inline iq5 & +iq5::operator+=(const iq5 &A) +{ + val += A.val; + return(*this); +} + +inline iq4 +operator+(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = A.val + B.val; + return(C); +} + +inline iq4 & +iq4::operator+=(const iq4 &A) +{ + val += A.val; + return(*this); +} + +inline iq3 +operator+(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = A.val + B.val; + return(C); +} + +inline iq3 & +iq3::operator+=(const iq3 &A) +{ + val += A.val; + return(*this); +} + +inline iq2 +operator+(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = A.val + B.val; + return(C); +} + +inline iq2 & +iq2::operator+=(const iq2 &A) +{ + val += A.val; + return(*this); +} + +inline iq1 +operator+(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = A.val + B.val; + return(C); +} + +inline iq1 & +iq1::operator+=(const iq1 &A) +{ + val += A.val; + return(*this); +} + +inline iq +operator+(const iq &A, const iq &B) +{ + iq C; + C.val = A.val + B.val; + return(C); +} + +inline iq & +iq::operator+=(const iq &A) +{ + val += A.val; + return(*this); +} + +//***************************************************************************** +// +// Operators "-" and "-=". +// +//***************************************************************************** +inline iq30 +operator-(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = A.val - B.val; + return(C); +} + +inline iq30 +operator-(const iq30 &A) +{ + iq30 B; + B.val = - A.val; + return(B); +} + +inline iq30 & +iq30::operator-=(const iq30 &A) +{ + val -= A.val; + return(*this); +} + +inline iq29 +operator-(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = A.val - B.val; + return(C); +} + +inline iq29 +operator-(const iq29 &A) +{ + iq29 B; + B.val = - A.val; + return(B); +} + +inline iq29 & +iq29::operator-=(const iq29 &A) +{ + val -= A.val; + return(*this); +} + +inline iq28 +operator-(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = A.val - B.val; + return(C); +} + +inline iq28 +operator-(const iq28 &A) +{ + iq28 B; + B.val = - A.val; + return(B); +} + +inline iq28 & +iq28::operator-=(const iq28 &A) +{ + val -= A.val; + return(*this); +} + +inline iq27 +operator-(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = A.val - B.val; + return(C); +} + +inline iq27 +operator-(const iq27 &A) +{ + iq27 B; + B.val = - A.val; + return(B); +} + +inline iq27 & +iq27::operator-=(const iq27 &A) +{ + val -= A.val; + return(*this); +} + +inline iq26 +operator-(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = A.val - B.val; + return(C); +} + +inline iq26 +operator-(const iq26 &A) +{ + iq26 B; + B.val = - A.val; + return(B); +} + +inline iq26 & +iq26::operator-=(const iq26 &A) +{ + val -= A.val; + return(*this); +} + +inline iq25 +operator-(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = A.val - B.val; + return(C); +} + +inline iq25 +operator-(const iq25 &A) +{ + iq25 B; + B.val = - A.val; + return(B); +} + +inline iq25 & +iq25::operator-=(const iq25 &A) +{ + val -= A.val; + return(*this); +} + +inline iq24 +operator-(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = A.val - B.val; + return(C); +} + +inline iq24 +operator-(const iq24 &A) +{ + iq24 B; + B.val = - A.val; + return(B); +} + +inline iq24 & +iq24::operator-=(const iq24 &A) +{ + val -= A.val; + return(*this); +} + +inline iq23 +operator-(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = A.val - B.val; + return(C); +} + +inline iq23 +operator-(const iq23 &A) +{ + iq23 B; + B.val = - A.val; + return(B); +} + +inline iq23 & +iq23::operator-=(const iq23 &A) +{ + val -= A.val; + return(*this); +} + +inline iq22 +operator-(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = A.val - B.val; + return(C); +} + +inline iq22 +operator-(const iq22 &A) +{ + iq22 B; + B.val = - A.val; + return(B); +} + +inline iq22 & +iq22::operator-=(const iq22 &A) +{ + val -= A.val; + return(*this); +} + +inline iq21 +operator-(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = A.val - B.val; + return(C); +} + +inline iq21 +operator-(const iq21 &A) +{ + iq21 B; + B.val = - A.val; + return(B); +} + +inline iq21 & +iq21::operator-=(const iq21 &A) +{ + val -= A.val; + return(*this); +} + +inline iq20 +operator-(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = A.val - B.val; + return(C); +} + +inline iq20 +operator-(const iq20 &A) +{ + iq20 B; + B.val = - A.val; + return(B); +} + +inline iq20 & +iq20::operator-=(const iq20 &A) +{ + val -= A.val; + return(*this); +} + +inline iq19 +operator-(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = A.val - B.val; + return(C); +} + +inline iq19 +operator-(const iq19 &A) +{ + iq19 B; + B.val = - A.val; + return(B); +} + +inline iq19 & +iq19::operator-=(const iq19 &A) +{ + val -= A.val; + return(*this); +} + +inline iq18 +operator-(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = A.val - B.val; + return(C); +} + +inline iq18 +operator-(const iq18 &A) +{ + iq18 B; + B.val = - A.val; + return(B); +} + +inline iq18 & +iq18::operator-=(const iq18 &A) +{ + val -= A.val; + return(*this); +} + +inline iq17 +operator-(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = A.val - B.val; + return(C); +} + +inline iq17 +operator-(const iq17 &A) +{ + iq17 B; + B.val = - A.val; + return(B); +} + +inline iq17 & +iq17::operator-=(const iq17 &A) +{ + val -= A.val; + return(*this); +} + +inline iq16 +operator-(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = A.val - B.val; + return(C); +} + +inline iq16 +operator-(const iq16 &A) +{ + iq16 B; + B.val = - A.val; + return(B); +} + +inline iq16 & +iq16::operator-=(const iq16 &A) +{ + val -= A.val; + return(*this); +} + +inline iq15 +operator-(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = A.val - B.val; + return(C); +} + +inline iq15 +operator-(const iq15 &A) +{ + iq15 B; + B.val = - A.val; + return(B); +} + +inline iq15 & +iq15::operator-=(const iq15 &A) +{ + val -= A.val; + return(*this); +} + +inline iq14 +operator-(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = A.val - B.val; + return(C); +} + +inline iq14 +operator-(const iq14 &A) +{ + iq14 B; + B.val = - A.val; + return(B); +} + +inline iq14 & +iq14::operator-=(const iq14 &A) +{ + val -= A.val; + return(*this); +} + +inline iq13 +operator-(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = A.val - B.val; + return(C); +} + +inline iq13 +operator-(const iq13 &A) +{ + iq13 B; + B.val = - A.val; + return(B); +} + +inline iq13 & +iq13::operator-=(const iq13 &A) +{ + val -= A.val; + return(*this); +} + +inline iq12 +operator-(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = A.val - B.val; + return(C); +} + +inline iq12 +operator-(const iq12 &A) +{ + iq12 B; + B.val = - A.val; + return(B); +} + +inline iq12 & +iq12::operator-=(const iq12 &A) +{ + val -= A.val; + return(*this); +} + +inline iq11 +operator-(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = A.val - B.val; + return(C); +} + +inline iq11 +operator-(const iq11 &A) +{ + iq11 B; + B.val = - A.val; + return(B); +} + +inline iq11 & +iq11::operator-=(const iq11 &A) +{ + val -= A.val; + return(*this); +} + +inline iq10 +operator-(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = A.val - B.val; + return(C); +} + +inline iq10 +operator-(const iq10 &A) +{ + iq10 B; + B.val = - A.val; + return(B); +} + +inline iq10 & +iq10::operator-=(const iq10 &A) +{ + val -= A.val; + return(*this); +} + +inline iq9 +operator-(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = A.val - B.val; + return(C); +} + +inline iq9 +operator-(const iq9 &A) +{ + iq9 B; + B.val = - A.val; + return(B); +} + +inline iq9 & +iq9::operator-=(const iq9 &A) +{ + val -= A.val; + return(*this); +} + +inline iq8 +operator-(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = A.val - B.val; + return(C); +} + +inline iq8 +operator-(const iq8 &A) +{ + iq8 B; + B.val = - A.val; + return(B); +} + +inline iq8 & +iq8::operator-=(const iq8 &A) +{ + val -= A.val; + return(*this); +} + +inline iq7 +operator-(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = A.val - B.val; + return(C); +} + +inline iq7 +operator-(const iq7 &A) +{ + iq7 B; + B.val = - A.val; + return(B); +} + +inline iq7 & +iq7::operator-=(const iq7 &A) +{ + val -= A.val; + return(*this); +} + +inline iq6 +operator-(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = A.val - B.val; + return(C); +} + +inline iq6 +operator-(const iq6 &A) +{ + iq6 B; + B.val = - A.val; + return(B); +} + +inline iq6 & +iq6::operator-=(const iq6 &A) +{ + val -= A.val; + return(*this); +} + +inline iq5 +operator-(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = A.val - B.val; + return(C); +} + +inline iq5 +operator-(const iq5 &A) +{ + iq5 B; + B.val = - A.val; + return(B); +} + +inline iq5 & +iq5::operator-=(const iq5 &A) +{ + val -= A.val; + return(*this); +} + +inline iq4 +operator-(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = A.val - B.val; + return(C); +} + +inline iq4 +operator-(const iq4 &A) +{ + iq4 B; + B.val = - A.val; + return(B); +} + +inline iq4 & +iq4::operator-=(const iq4 &A) +{ + val -= A.val; + return(*this); +} + +inline iq3 +operator-(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = A.val - B.val; + return(C); +} + +inline iq3 +operator-(const iq3 &A) +{ + iq3 B; + B.val = - A.val; + return(B); +} + +inline iq3 & +iq3::operator-=(const iq3 &A) +{ + val -= A.val; + return(*this); +} + +inline iq2 +operator-(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = A.val - B.val; + return(C); +} + +inline iq2 +operator-(const iq2 &A) +{ + iq2 B; + B.val = - A.val; + return(B); +} + +inline iq2 & +iq2::operator-=(const iq2 &A) +{ + val -= A.val; + return(*this); +} + +inline iq1 +operator-(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = A.val - B.val; + return(C); +} + +inline iq1 +operator-(const iq1 &A) +{ + iq1 B; + B.val = - A.val; + return(B); +} + +inline iq1 & +iq1::operator-=(const iq1 &A) +{ + val -= A.val; + return(*this); +} + +inline iq +operator-(const iq &A, const iq &B) +{ + iq C; + C.val = A.val - B.val; + return(C); +} + +inline iq +operator-(const iq &A) +{ + iq B; + B.val = - A.val; + return(B); +} + +inline iq & +iq::operator-=(const iq &A) +{ + val -= A.val; + return(*this); +} + +//***************************************************************************** +// +// Operators "*" and "*=". +// +//***************************************************************************** +inline iq30 +operator*(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30mpy(A.val, B.val); + return(C); +} + +inline iq30 & +iq30::operator*=(const iq30 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq29 +operator*(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29mpy(A.val, B.val); + return(C); +} + +inline iq29 & +iq29::operator*=(const iq29 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq28 +operator*(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28mpy(A.val, B.val); + return(C); +} + +inline iq28 & +iq28::operator*=(const iq28 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq27 +operator*(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27mpy(A.val, B.val); + return(C); +} + +inline iq27 & +iq27::operator*=(const iq27 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq26 +operator*(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26mpy(A.val, B.val); + return(C); +} + +inline iq26 & +iq26::operator*=(const iq26 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq25 +operator*(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25mpy(A.val, B.val); + return(C); +} + +inline iq25 & +iq25::operator*=(const iq25 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq24 +operator*(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24mpy(A.val, B.val); + return(C); +} + +inline iq24 & +iq24::operator*=(const iq24 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq23 +operator*(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23mpy(A.val, B.val); + return(C); +} + +inline iq23 & +iq23::operator*=(const iq23 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq22 +operator*(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22mpy(A.val, B.val); + return(C); +} + +inline iq22 & +iq22::operator*=(const iq22 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq21 +operator*(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21mpy(A.val, B.val); + return(C); +} + +inline iq21 & +iq21::operator*=(const iq21 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq20 +operator*(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20mpy(A.val, B.val); + return(C); +} + +inline iq20 & +iq20::operator*=(const iq20 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq19 +operator*(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19mpy(A.val, B.val); + return(C); +} + +inline iq19 & +iq19::operator*=(const iq19 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq18 +operator*(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18mpy(A.val, B.val); + return(C); +} + +inline iq18 & +iq18::operator*=(const iq18 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq17 +operator*(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17mpy(A.val, B.val); + return(C); +} + +inline iq17 & +iq17::operator*=(const iq17 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq16 +operator*(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16mpy(A.val, B.val); + return(C); +} + +inline iq16 & +iq16::operator*=(const iq16 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq15 +operator*(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15mpy(A.val, B.val); + return(C); +} + +inline iq15 & +iq15::operator*=(const iq15 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq14 +operator*(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14mpy(A.val, B.val); + return(C); +} + +inline iq14 & +iq14::operator*=(const iq14 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq13 +operator*(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13mpy(A.val, B.val); + return(C); +} + +inline iq13 & +iq13::operator*=(const iq13 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq12 +operator*(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12mpy(A.val, B.val); + return(C); +} + +inline iq12 & +iq12::operator*=(const iq12 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq11 +operator*(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11mpy(A.val, B.val); + return(C); +} + +inline iq11 & +iq11::operator*=(const iq11 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq10 +operator*(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10mpy(A.val, B.val); + return(C); +} + +inline iq10 & +iq10::operator*=(const iq10 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq9 +operator*(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9mpy(A.val, B.val); + return(C); +} + +inline iq9 & +iq9::operator*=(const iq9 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq8 +operator*(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8mpy(A.val, B.val); + return(C); +} + +inline iq8 & +iq8::operator*=(const iq8 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq7 +operator*(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7mpy(A.val, B.val); + return(C); +} + +inline iq7 & +iq7::operator*=(const iq7 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq6 +operator*(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6mpy(A.val, B.val); + return(C); +} + +inline iq6 & +iq6::operator*=(const iq6 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq5 +operator*(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5mpy(A.val, B.val); + return(C); +} + +inline iq5 & +iq5::operator*=(const iq5 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq4 +operator*(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4mpy(A.val, B.val); + return(C); +} + +inline iq4 & +iq4::operator*=(const iq4 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq3 +operator*(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3mpy(A.val, B.val); + return(C); +} + +inline iq3 & +iq3::operator*=(const iq3 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq2 +operator*(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2mpy(A.val, B.val); + return(C); +} + +inline iq2 & +iq2::operator*=(const iq2 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq1 +operator*(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1mpy(A.val, B.val); + return(C); +} + +inline iq1 & +iq1::operator*=(const iq1 &A) +{ + val = _IQ30mpy(val, A.val); + return(*this); +} + +inline iq +operator*(const iq &A, const iq &B) +{ + iq C; + C.val = _IQmpy(A.val, B.val); + return(C); +} + +inline iq & +iq::operator*=(const iq &A) +{ + val = _IQmpy(val, A.val); + return(*this); +} + +//***************************************************************************** +// +// Operators "/" and "/=". +// +//***************************************************************************** +inline iq30 +operator/(const iq30 &A, const iq30 &B) +{ + iq30 C; + C.val = _IQ30div(A.val, B.val); + return(C); +} + +inline iq30 & +iq30::operator/=(const iq30 &A) +{ + val = _IQ30div(val, A.val); + return(*this); +} + +inline iq29 +operator/(const iq29 &A, const iq29 &B) +{ + iq29 C; + C.val = _IQ29div(A.val, B.val); + return(C); +} + +inline iq29 & +iq29::operator/=(const iq29 &A) +{ + val = _IQ29div(val, A.val); + return(*this); +} + +inline iq28 +operator/(const iq28 &A, const iq28 &B) +{ + iq28 C; + C.val = _IQ28div(A.val, B.val); + return(C); +} + +inline iq28 & +iq28::operator/=(const iq28 &A) +{ + val = _IQ28div(val, A.val); + return(*this); +} + +inline iq27 +operator/(const iq27 &A, const iq27 &B) +{ + iq27 C; + C.val = _IQ27div(A.val, B.val); + return(C); +} + +inline iq27 & +iq27::operator/=(const iq27 &A) +{ + val = _IQ27div(val, A.val); + return(*this); +} + +inline iq26 +operator/(const iq26 &A, const iq26 &B) +{ + iq26 C; + C.val = _IQ26div(A.val, B.val); + return(C); +} + +inline iq26 & +iq26::operator/=(const iq26 &A) +{ + val = _IQ26div(val, A.val); + return(*this); +} + +inline iq25 +operator/(const iq25 &A, const iq25 &B) +{ + iq25 C; + C.val = _IQ25div(A.val, B.val); + return(C); +} + +inline iq25 & +iq25::operator/=(const iq25 &A) +{ + val = _IQ25div(val, A.val); + return(*this); +} + +inline iq24 +operator/(const iq24 &A, const iq24 &B) +{ + iq24 C; + C.val = _IQ24div(A.val, B.val); + return(C); +} + +inline iq24 & +iq24::operator/=(const iq24 &A) +{ + val = _IQ24div(val, A.val); + return(*this); +} + +inline iq23 +operator/(const iq23 &A, const iq23 &B) +{ + iq23 C; + C.val = _IQ23div(A.val, B.val); + return(C); +} + +inline iq23 & +iq23::operator/=(const iq23 &A) +{ + val = _IQ23div(val, A.val); + return(*this); +} + +inline iq22 +operator/(const iq22 &A, const iq22 &B) +{ + iq22 C; + C.val = _IQ22div(A.val, B.val); + return(C); +} + +inline iq22 & +iq22::operator/=(const iq22 &A) +{ + val = _IQ22div(val, A.val); + return(*this); +} + +inline iq21 +operator/(const iq21 &A, const iq21 &B) +{ + iq21 C; + C.val = _IQ21div(A.val, B.val); + return(C); +} + +inline iq21 & +iq21::operator/=(const iq21 &A) +{ + val = _IQ21div(val, A.val); + return(*this); +} + +inline iq20 +operator/(const iq20 &A, const iq20 &B) +{ + iq20 C; + C.val = _IQ20div(A.val, B.val); + return(C); +} + +inline iq20 & +iq20::operator/=(const iq20 &A) +{ + val = _IQ20div(val, A.val); + return(*this); +} + +inline iq19 +operator/(const iq19 &A, const iq19 &B) +{ + iq19 C; + C.val = _IQ19div(A.val, B.val); + return(C); +} + +inline iq19 & +iq19::operator/=(const iq19 &A) +{ + val = _IQ19div(val, A.val); + return(*this); +} + +inline iq18 +operator/(const iq18 &A, const iq18 &B) +{ + iq18 C; + C.val = _IQ18div(A.val, B.val); + return(C); +} + +inline iq18 & +iq18::operator/=(const iq18 &A) +{ + val = _IQ18div(val, A.val); + return(*this); +} + +inline iq17 +operator/(const iq17 &A, const iq17 &B) +{ + iq17 C; + C.val = _IQ17div(A.val, B.val); + return(C); +} + +inline iq17 & +iq17::operator/=(const iq17 &A) +{ + val = _IQ17div(val, A.val); + return(*this); +} + +inline iq16 +operator/(const iq16 &A, const iq16 &B) +{ + iq16 C; + C.val = _IQ16div(A.val, B.val); + return(C); +} + +inline iq16 & +iq16::operator/=(const iq16 &A) +{ + val = _IQ16div(val, A.val); + return(*this); +} + +inline iq15 +operator/(const iq15 &A, const iq15 &B) +{ + iq15 C; + C.val = _IQ15div(A.val, B.val); + return(C); +} + +inline iq15 & +iq15::operator/=(const iq15 &A) +{ + val = _IQ15div(val, A.val); + return(*this); +} + +inline iq14 +operator/(const iq14 &A, const iq14 &B) +{ + iq14 C; + C.val = _IQ14div(A.val, B.val); + return(C); +} + +inline iq14 & +iq14::operator/=(const iq14 &A) +{ + val = _IQ14div(val, A.val); + return(*this); +} + +inline iq13 +operator/(const iq13 &A, const iq13 &B) +{ + iq13 C; + C.val = _IQ13div(A.val, B.val); + return(C); +} + +inline iq13 & +iq13::operator/=(const iq13 &A) +{ + val = _IQ13div(val, A.val); + return(*this); +} + +inline iq12 +operator/(const iq12 &A, const iq12 &B) +{ + iq12 C; + C.val = _IQ12div(A.val, B.val); + return(C); +} + +inline iq12 & +iq12::operator/=(const iq12 &A) +{ + val = _IQ12div(val, A.val); + return(*this); +} + +inline iq11 +operator/(const iq11 &A, const iq11 &B) +{ + iq11 C; + C.val = _IQ11div(A.val, B.val); + return(C); +} + +inline iq11 & +iq11::operator/=(const iq11 &A) +{ + val = _IQ11div(val, A.val); + return(*this); +} + +inline iq10 +operator/(const iq10 &A, const iq10 &B) +{ + iq10 C; + C.val = _IQ10div(A.val, B.val); + return(C); +} + +inline iq10 & +iq10::operator/=(const iq10 &A) +{ + val = _IQ10div(val, A.val); + return(*this); +} + +inline iq9 +operator/(const iq9 &A, const iq9 &B) +{ + iq9 C; + C.val = _IQ9div(A.val, B.val); + return(C); +} + +inline iq9 & +iq9::operator/=(const iq9 &A) +{ + val = _IQ9div(val, A.val); + return(*this); +} + +inline iq8 +operator/(const iq8 &A, const iq8 &B) +{ + iq8 C; + C.val = _IQ8div(A.val, B.val); + return(C); +} + +inline iq8 & +iq8::operator/=(const iq8 &A) +{ + val = _IQ8div(val, A.val); + return(*this); +} + +inline iq7 +operator/(const iq7 &A, const iq7 &B) +{ + iq7 C; + C.val = _IQ7div(A.val, B.val); + return(C); +} + +inline iq7 & +iq7::operator/=(const iq7 &A) +{ + val = _IQ7div(val, A.val); + return(*this); +} + +inline iq6 +operator/(const iq6 &A, const iq6 &B) +{ + iq6 C; + C.val = _IQ6div(A.val, B.val); + return(C); +} + +inline iq6 & +iq6::operator/=(const iq6 &A) +{ + val = _IQ6div(val, A.val); + return(*this); +} + +inline iq5 +operator/(const iq5 &A, const iq5 &B) +{ + iq5 C; + C.val = _IQ5div(A.val, B.val); + return(C); +} + +inline iq5 & +iq5::operator/=(const iq5 &A) +{ + val = _IQ5div(val, A.val); + return(*this); +} + +inline iq4 +operator/(const iq4 &A, const iq4 &B) +{ + iq4 C; + C.val = _IQ4div(A.val, B.val); + return(C); +} + +inline iq4 & +iq4::operator/=(const iq4 &A) +{ + val = _IQ4div(val, A.val); + return(*this); +} + +inline iq3 +operator/(const iq3 &A, const iq3 &B) +{ + iq3 C; + C.val = _IQ3div(A.val, B.val); + return(C); +} + +inline iq3 & +iq3::operator/=(const iq3 &A) +{ + val = _IQ3div(val, A.val); + return(*this); +} + +inline iq2 +operator/(const iq2 &A, const iq2 &B) +{ + iq2 C; + C.val = _IQ2div(A.val, B.val); + return(C); +} + +inline iq2 & +iq2::operator/=(const iq2 &A) +{ + val = _IQ2div(val, A.val); + return(*this); +} + +inline iq1 +operator/(const iq1 &A, const iq1 &B) +{ + iq1 C; + C.val = _IQ1div(A.val, B.val); + return(C); +} + +inline iq1 & +iq1::operator/=(const iq1 &A) +{ + val = _IQ1div(val, A.val); + return(*this); +} + +inline iq +operator/(const iq &A, const iq &B) +{ + iq C; + C.val = _IQdiv(A.val, B.val); + return(C); +} + +inline iq & +iq::operator/=(const iq &A) +{ + val = _IQdiv(val, A.val); + return(*this); +} + +//***************************************************************************** +// +// Operators "==", "!=", "<", ">", "<=", ">=", "&&", and "||". +// +//***************************************************************************** +inline bool +operator==(const iq30 &A, const iq30 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq30 &A, const iq30 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq30 &A, const iq30 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq30 &A, const iq30 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq30 &A, const iq30 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq30 &A, const iq30 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq30 &A, const iq30 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq30 &A, const iq30 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq29 &A, const iq29 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq29 &A, const iq29 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq29 &A, const iq29 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq29 &A, const iq29 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq29 &A, const iq29 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq29 &A, const iq29 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq29 &A, const iq29 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq29 &A, const iq29 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq28 &A, const iq28 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq28 &A, const iq28 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq28 &A, const iq28 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq28 &A, const iq28 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq28 &A, const iq28 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq28 &A, const iq28 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq28 &A, const iq28 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq28 &A, const iq28 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq27 &A, const iq27 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq27 &A, const iq27 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq27 &A, const iq27 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq27 &A, const iq27 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq27 &A, const iq27 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq27 &A, const iq27 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq27 &A, const iq27 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq27 &A, const iq27 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq26 &A, const iq26 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq26 &A, const iq26 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq26 &A, const iq26 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq26 &A, const iq26 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq26 &A, const iq26 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq26 &A, const iq26 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq26 &A, const iq26 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq26 &A, const iq26 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq25 &A, const iq25 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq25 &A, const iq25 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq25 &A, const iq25 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq25 &A, const iq25 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq25 &A, const iq25 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq25 &A, const iq25 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq25 &A, const iq25 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq25 &A, const iq25 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq24 &A, const iq24 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq24 &A, const iq24 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq24 &A, const iq24 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq24 &A, const iq24 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq24 &A, const iq24 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq24 &A, const iq24 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq24 &A, const iq24 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq24 &A, const iq24 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq23 &A, const iq23 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq23 &A, const iq23 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq23 &A, const iq23 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq23 &A, const iq23 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq23 &A, const iq23 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq23 &A, const iq23 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq23 &A, const iq23 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq23 &A, const iq23 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq22 &A, const iq22 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq22 &A, const iq22 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq22 &A, const iq22 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq22 &A, const iq22 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq22 &A, const iq22 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq22 &A, const iq22 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq22 &A, const iq22 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq22 &A, const iq22 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq21 &A, const iq21 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq21 &A, const iq21 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq21 &A, const iq21 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq21 &A, const iq21 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq21 &A, const iq21 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq21 &A, const iq21 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq21 &A, const iq21 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq21 &A, const iq21 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq20 &A, const iq20 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq20 &A, const iq20 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq20 &A, const iq20 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq20 &A, const iq20 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq20 &A, const iq20 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq20 &A, const iq20 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq20 &A, const iq20 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq20 &A, const iq20 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq19 &A, const iq19 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq19 &A, const iq19 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq19 &A, const iq19 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq19 &A, const iq19 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq19 &A, const iq19 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq19 &A, const iq19 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq19 &A, const iq19 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq19 &A, const iq19 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq18 &A, const iq18 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq18 &A, const iq18 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq18 &A, const iq18 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq18 &A, const iq18 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq18 &A, const iq18 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq18 &A, const iq18 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq18 &A, const iq18 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq18 &A, const iq18 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq17 &A, const iq17 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq17 &A, const iq17 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq17 &A, const iq17 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq17 &A, const iq17 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq17 &A, const iq17 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq17 &A, const iq17 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq17 &A, const iq17 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq17 &A, const iq17 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq16 &A, const iq16 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq16 &A, const iq16 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq16 &A, const iq16 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq16 &A, const iq16 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq16 &A, const iq16 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq16 &A, const iq16 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq16 &A, const iq16 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq16 &A, const iq16 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq15 &A, const iq15 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq15 &A, const iq15 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq15 &A, const iq15 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq15 &A, const iq15 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq15 &A, const iq15 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq15 &A, const iq15 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq15 &A, const iq15 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq15 &A, const iq15 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq14 &A, const iq14 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq14 &A, const iq14 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq14 &A, const iq14 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq14 &A, const iq14 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq14 &A, const iq14 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq14 &A, const iq14 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq14 &A, const iq14 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq14 &A, const iq14 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq13 &A, const iq13 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq13 &A, const iq13 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq13 &A, const iq13 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq13 &A, const iq13 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq13 &A, const iq13 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq13 &A, const iq13 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq13 &A, const iq13 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq13 &A, const iq13 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq12 &A, const iq12 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq12 &A, const iq12 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq12 &A, const iq12 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq12 &A, const iq12 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq12 &A, const iq12 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq12 &A, const iq12 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq12 &A, const iq12 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq12 &A, const iq12 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq11 &A, const iq11 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq11 &A, const iq11 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq11 &A, const iq11 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq11 &A, const iq11 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq11 &A, const iq11 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq11 &A, const iq11 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq11 &A, const iq11 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq11 &A, const iq11 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq10 &A, const iq10 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq10 &A, const iq10 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq10 &A, const iq10 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq10 &A, const iq10 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq10 &A, const iq10 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq10 &A, const iq10 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq10 &A, const iq10 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq10 &A, const iq10 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq9 &A, const iq9 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq9 &A, const iq9 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq9 &A, const iq9 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq9 &A, const iq9 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq9 &A, const iq9 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq9 &A, const iq9 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq9 &A, const iq9 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq9 &A, const iq9 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq8 &A, const iq8 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq8 &A, const iq8 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq8 &A, const iq8 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq8 &A, const iq8 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq8 &A, const iq8 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq8 &A, const iq8 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq8 &A, const iq8 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq8 &A, const iq8 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq7 &A, const iq7 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq7 &A, const iq7 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq7 &A, const iq7 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq7 &A, const iq7 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq7 &A, const iq7 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq7 &A, const iq7 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq7 &A, const iq7 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq7 &A, const iq7 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq6 &A, const iq6 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq6 &A, const iq6 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq6 &A, const iq6 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq6 &A, const iq6 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq6 &A, const iq6 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq6 &A, const iq6 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq6 &A, const iq6 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq6 &A, const iq6 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq5 &A, const iq5 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq5 &A, const iq5 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq5 &A, const iq5 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq5 &A, const iq5 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq5 &A, const iq5 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq5 &A, const iq5 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq5 &A, const iq5 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq5 &A, const iq5 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq4 &A, const iq4 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq4 &A, const iq4 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq4 &A, const iq4 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq4 &A, const iq4 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq4 &A, const iq4 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq4 &A, const iq4 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq4 &A, const iq4 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq4 &A, const iq4 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq3 &A, const iq3 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq3 &A, const iq3 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq3 &A, const iq3 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq3 &A, const iq3 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq3 &A, const iq3 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq3 &A, const iq3 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq3 &A, const iq3 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq3 &A, const iq3 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq2 &A, const iq2 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq2 &A, const iq2 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq2 &A, const iq2 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq2 &A, const iq2 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq2 &A, const iq2 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq2 &A, const iq2 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq2 &A, const iq2 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq2 &A, const iq2 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq1 &A, const iq1 &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq1 &A, const iq1 &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq1 &A, const iq1 &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq1 &A, const iq1 &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq1 &A, const iq1 &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq1 &A, const iq1 &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq1 &A, const iq1 &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq1 &A, const iq1 &B) +{ + return(A.val || B.val); +} + +inline bool +operator==(const iq &A, const iq &B) +{ + return(A.val == B.val); +} + +inline bool +operator!=(const iq &A, const iq &B) +{ + return(A.val != B.val); +} + +inline bool +operator<(const iq &A, const iq &B) +{ + return(A.val < B.val); +} + +inline bool +operator>(const iq &A, const iq &B) +{ + return(A.val > B.val); +} + +inline bool +operator<=(const iq &A, const iq &B) +{ + return(A.val <= B.val); +} + +inline bool +operator>=(const iq &A, const iq &B) +{ + return(A.val >= B.val); +} + +inline bool +operator&&(const iq &A, const iq &B) +{ + return(A.val && B.val); +} + +inline bool +operator||(const iq &A, const iq &B) +{ + return(A.val || B.val); +} + +//***************************************************************************** +// +// Operators "&" and "&=". +// +//***************************************************************************** +inline iq30 +operator&(const iq30 &A, const long &B) +{ + iq30 C; + C.val = A.val & B; + return(C); +} + +inline iq30 & +iq30::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq29 +operator&(const iq29 &A, const long &B) +{ + iq29 C; + C.val = A.val & B; + return(C); +} + +inline iq29 & +iq29::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq28 +operator&(const iq28 &A, const long &B) +{ + iq28 C; + C.val = A.val & B; + return(C); +} + +inline iq28 & +iq28::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq27 +operator&(const iq27 &A, const long &B) +{ + iq27 C; + C.val = A.val & B; + return(C); +} + +inline iq27 & +iq27::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq26 +operator&(const iq26 &A, const long &B) +{ + iq26 C; + C.val = A.val & B; + return(C); +} + +inline iq26 & +iq26::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq25 +operator&(const iq25 &A, const long &B) +{ + iq25 C; + C.val = A.val & B; + return(C); +} + +inline iq25 & +iq25::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq24 +operator&(const iq24 &A, const long &B) +{ + iq24 C; + C.val = A.val & B; + return(C); +} + +inline iq24 & +iq24::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq23 +operator&(const iq23 &A, const long &B) +{ + iq23 C; + C.val = A.val & B; + return(C); +} + +inline iq23 & +iq23::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq22 +operator&(const iq22 &A, const long &B) +{ + iq22 C; + C.val = A.val & B; + return(C); +} + +inline iq22 & +iq22::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq21 +operator&(const iq21 &A, const long &B) +{ + iq21 C; + C.val = A.val & B; + return(C); +} + +inline iq21 & +iq21::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq20 +operator&(const iq20 &A, const long &B) +{ + iq20 C; + C.val = A.val & B; + return(C); +} + +inline iq20 & +iq20::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq19 +operator&(const iq19 &A, const long &B) +{ + iq19 C; + C.val = A.val & B; + return(C); +} + +inline iq19 & +iq19::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq18 +operator&(const iq18 &A, const long &B) +{ + iq18 C; + C.val = A.val & B; + return(C); +} + +inline iq18 & +iq18::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq17 +operator&(const iq17 &A, const long &B) +{ + iq17 C; + C.val = A.val & B; + return(C); +} + +inline iq17 & +iq17::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq16 +operator&(const iq16 &A, const long &B) +{ + iq16 C; + C.val = A.val & B; + return(C); +} + +inline iq16 & +iq16::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq15 +operator&(const iq15 &A, const long &B) +{ + iq15 C; + C.val = A.val & B; + return(C); +} + +inline iq15 & +iq15::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq14 +operator&(const iq14 &A, const long &B) +{ + iq14 C; + C.val = A.val & B; + return(C); +} + +inline iq14 & +iq14::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq13 +operator&(const iq13 &A, const long &B) +{ + iq13 C; + C.val = A.val & B; + return(C); +} + +inline iq13 & +iq13::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq12 +operator&(const iq12 &A, const long &B) +{ + iq12 C; + C.val = A.val & B; + return(C); +} + +inline iq12 & +iq12::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq11 +operator&(const iq11 &A, const long &B) +{ + iq11 C; + C.val = A.val & B; + return(C); +} + +inline iq11 & +iq11::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq10 +operator&(const iq10 &A, const long &B) +{ + iq10 C; + C.val = A.val & B; + return(C); +} + +inline iq10 & +iq10::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq9 +operator&(const iq9 &A, const long &B) +{ + iq9 C; + C.val = A.val & B; + return(C); +} + +inline iq9 & +iq9::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq8 +operator&(const iq8 &A, const long &B) +{ + iq8 C; + C.val = A.val & B; + return(C); +} + +inline iq8 & +iq8::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq7 +operator&(const iq7 &A, const long &B) +{ + iq7 C; + C.val = A.val & B; + return(C); +} + +inline iq7 & +iq7::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq6 +operator&(const iq6 &A, const long &B) +{ + iq6 C; + C.val = A.val & B; + return(C); +} + +inline iq6 & +iq6::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq5 +operator&(const iq5 &A, const long &B) +{ + iq5 C; + C.val = A.val & B; + return(C); +} + +inline iq5 & +iq5::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq4 +operator&(const iq4 &A, const long &B) +{ + iq4 C; + C.val = A.val & B; + return(C); +} + +inline iq4 & +iq4::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq3 +operator&(const iq3 &A, const long &B) +{ + iq3 C; + C.val = A.val & B; + return(C); +} + +inline iq3 & +iq3::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq2 +operator&(const iq2 &A, const long &B) +{ + iq2 C; + C.val = A.val & B; + return(C); +} + +inline iq2 & +iq2::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq1 +operator&(const iq1 &A, const long &B) +{ + iq1 C; + C.val = A.val & B; + return(C); +} + +inline iq1 & +iq1::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +inline iq +operator&(const iq &A, const long &B) +{ + iq C; + C.val = A.val & B; + return(C); +} + +inline iq & +iq::operator&=(const long &A) +{ + val &= A; + return(*this); +} + +//***************************************************************************** +// +// Operators "|" and "|=". +// +//***************************************************************************** +inline iq30 +operator|(const iq30 &A, const long &B) +{ + iq30 C; + C.val = A.val | B; + return(C); +} + +inline iq30 & +iq30::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq29 +operator|(const iq29 &A, const long &B) +{ + iq29 C; + C.val = A.val | B; + return(C); +} + +inline iq29 & +iq29::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq28 +operator|(const iq28 &A, const long &B) +{ + iq28 C; + C.val = A.val | B; + return(C); +} + +inline iq28 & +iq28::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq27 +operator|(const iq27 &A, const long &B) +{ + iq27 C; + C.val = A.val | B; + return(C); +} + +inline iq27 & +iq27::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq26 +operator|(const iq26 &A, const long &B) +{ + iq26 C; + C.val = A.val | B; + return(C); +} + +inline iq26 & +iq26::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq25 +operator|(const iq25 &A, const long &B) +{ + iq25 C; + C.val = A.val | B; + return(C); +} + +inline iq25 & +iq25::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq24 +operator|(const iq24 &A, const long &B) +{ + iq24 C; + C.val = A.val | B; + return(C); +} + +inline iq24 & +iq24::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq23 +operator|(const iq23 &A, const long &B) +{ + iq23 C; + C.val = A.val | B; + return(C); +} + +inline iq23 & +iq23::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq22 +operator|(const iq22 &A, const long &B) +{ + iq22 C; + C.val = A.val | B; + return(C); +} + +inline iq22 & +iq22::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq21 +operator|(const iq21 &A, const long &B) +{ + iq21 C; + C.val = A.val | B; + return(C); +} + +inline iq21 & +iq21::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq20 +operator|(const iq20 &A, const long &B) +{ + iq20 C; + C.val = A.val | B; + return(C); +} + +inline iq20 & +iq20::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq19 +operator|(const iq19 &A, const long &B) +{ + iq19 C; + C.val = A.val | B; + return(C); +} + +inline iq19 & +iq19::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq18 +operator|(const iq18 &A, const long &B) +{ + iq18 C; + C.val = A.val | B; + return(C); +} + +inline iq18 & +iq18::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq17 +operator|(const iq17 &A, const long &B) +{ + iq17 C; + C.val = A.val | B; + return(C); +} + +inline iq17 & +iq17::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq16 +operator|(const iq16 &A, const long &B) +{ + iq16 C; + C.val = A.val | B; + return(C); +} + +inline iq16 & +iq16::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq15 +operator|(const iq15 &A, const long &B) +{ + iq15 C; + C.val = A.val | B; + return(C); +} + +inline iq15 & +iq15::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq14 +operator|(const iq14 &A, const long &B) +{ + iq14 C; + C.val = A.val | B; + return(C); +} + +inline iq14 & +iq14::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq13 +operator|(const iq13 &A, const long &B) +{ + iq13 C; + C.val = A.val | B; + return(C); +} + +inline iq13 & +iq13::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq12 +operator|(const iq12 &A, const long &B) +{ + iq12 C; + C.val = A.val | B; + return(C); +} + +inline iq12 & +iq12::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq11 +operator|(const iq11 &A, const long &B) +{ + iq11 C; + C.val = A.val | B; + return(C); +} + +inline iq11 & +iq11::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq10 +operator|(const iq10 &A, const long &B) +{ + iq10 C; + C.val = A.val | B; + return(C); +} + +inline iq10 & +iq10::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq9 +operator|(const iq9 &A, const long &B) +{ + iq9 C; + C.val = A.val | B; + return(C); +} + +inline iq9 & +iq9::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq8 +operator|(const iq8 &A, const long &B) +{ + iq8 C; + C.val = A.val | B; + return(C); +} + +inline iq8 & +iq8::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq7 +operator|(const iq7 &A, const long &B) +{ + iq7 C; + C.val = A.val | B; + return(C); +} + +inline iq7 & +iq7::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq6 +operator|(const iq6 &A, const long &B) +{ + iq6 C; + C.val = A.val | B; + return(C); +} + +inline iq6 & +iq6::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq5 +operator|(const iq5 &A, const long &B) +{ + iq5 C; + C.val = A.val | B; + return(C); +} + +inline iq5 & +iq5::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq4 +operator|(const iq4 &A, const long &B) +{ + iq4 C; + C.val = A.val | B; + return(C); +} + +inline iq4 & +iq4::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq3 +operator|(const iq3 &A, const long &B) +{ + iq3 C; + C.val = A.val | B; + return(C); +} + +inline iq3 & +iq3::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq2 +operator|(const iq2 &A, const long &B) +{ + iq2 C; + C.val = A.val | B; + return(C); +} + +inline iq2 & +iq2::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq1 +operator|(const iq1 &A, const long &B) +{ + iq1 C; + C.val = A.val | B; + return(C); +} + +inline iq1 & +iq1::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +inline iq +operator|(const iq &A, const long &B) +{ + iq C; + C.val = A.val | B; + return(C); +} + +inline iq & +iq::operator|=(const long &A) +{ + val |= A; + return(*this); +} + +//***************************************************************************** +// +// Operators "^" and "^=". +// +//***************************************************************************** +inline iq30 +operator^(const iq30 &A, const long &B) +{ + iq30 C; + C.val = A.val ^ B; + return(C); +} + +inline iq30 & +iq30::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq29 +operator^(const iq29 &A, const long &B) +{ + iq29 C; + C.val = A.val ^ B; + return(C); +} + +inline iq29 & +iq29::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq28 +operator^(const iq28 &A, const long &B) +{ + iq28 C; + C.val = A.val ^ B; + return(C); +} + +inline iq28 & +iq28::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq27 +operator^(const iq27 &A, const long &B) +{ + iq27 C; + C.val = A.val ^ B; + return(C); +} + +inline iq27 & +iq27::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq26 +operator^(const iq26 &A, const long &B) +{ + iq26 C; + C.val = A.val ^ B; + return(C); +} + +inline iq26 & +iq26::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq25 +operator^(const iq25 &A, const long &B) +{ + iq25 C; + C.val = A.val ^ B; + return(C); +} + +inline iq25 & +iq25::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq24 +operator^(const iq24 &A, const long &B) +{ + iq24 C; + C.val = A.val ^ B; + return(C); +} + +inline iq24 & +iq24::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq23 +operator^(const iq23 &A, const long &B) +{ + iq23 C; + C.val = A.val ^ B; + return(C); +} + +inline iq23 & +iq23::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq22 +operator^(const iq22 &A, const long &B) +{ + iq22 C; + C.val = A.val ^ B; + return(C); +} + +inline iq22 & +iq22::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq21 +operator^(const iq21 &A, const long &B) +{ + iq21 C; + C.val = A.val ^ B; + return(C); +} + +inline iq21 & +iq21::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq20 +operator^(const iq20 &A, const long &B) +{ + iq20 C; + C.val = A.val ^ B; + return(C); +} + +inline iq20 & +iq20::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq19 +operator^(const iq19 &A, const long &B) +{ + iq19 C; + C.val = A.val ^ B; + return(C); +} + +inline iq19 & +iq19::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq18 +operator^(const iq18 &A, const long &B) +{ + iq18 C; + C.val = A.val ^ B; + return(C); +} + +inline iq18 & +iq18::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq17 +operator^(const iq17 &A, const long &B) +{ + iq17 C; + C.val = A.val ^ B; + return(C); +} + +inline iq17 & +iq17::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq16 +operator^(const iq16 &A, const long &B) +{ + iq16 C; + C.val = A.val ^ B; + return(C); +} + +inline iq16 & +iq16::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq15 +operator^(const iq15 &A, const long &B) +{ + iq15 C; + C.val = A.val ^ B; + return(C); +} + +inline iq15 & +iq15::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq14 +operator^(const iq14 &A, const long &B) +{ + iq14 C; + C.val = A.val ^ B; + return(C); +} + +inline iq14 & +iq14::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq13 +operator^(const iq13 &A, const long &B) +{ + iq13 C; + C.val = A.val ^ B; + return(C); +} + +inline iq13 & +iq13::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq12 +operator^(const iq12 &A, const long &B) +{ + iq12 C; + C.val = A.val ^ B; + return(C); +} + +inline iq12 & +iq12::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq11 +operator^(const iq11 &A, const long &B) +{ + iq11 C; + C.val = A.val ^ B; + return(C); +} + +inline iq11 & +iq11::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq10 +operator^(const iq10 &A, const long &B) +{ + iq10 C; + C.val = A.val ^ B; + return(C); +} + +inline iq10 & +iq10::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq9 +operator^(const iq9 &A, const long &B) +{ + iq9 C; + C.val = A.val ^ B; + return(C); +} + +inline iq9 & +iq9::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq8 +operator^(const iq8 &A, const long &B) +{ + iq8 C; + C.val = A.val ^ B; + return(C); +} + +inline iq8 & +iq8::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq7 +operator^(const iq7 &A, const long &B) +{ + iq7 C; + C.val = A.val ^ B; + return(C); +} + +inline iq7 & +iq7::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq6 +operator^(const iq6 &A, const long &B) +{ + iq6 C; + C.val = A.val ^ B; + return(C); +} + +inline iq6 & +iq6::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq5 +operator^(const iq5 &A, const long &B) +{ + iq5 C; + C.val = A.val ^ B; + return(C); +} + +inline iq5 & +iq5::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq4 +operator^(const iq4 &A, const long &B) +{ + iq4 C; + C.val = A.val ^ B; + return(C); +} + +inline iq4 & +iq4::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq3 +operator^(const iq3 &A, const long &B) +{ + iq3 C; + C.val = A.val ^ B; + return(C); +} + +inline iq3 & +iq3::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq2 +operator^(const iq2 &A, const long &B) +{ + iq2 C; + C.val = A.val ^ B; + return(C); +} + +inline iq2 & +iq2::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq1 +operator^(const iq1 &A, const long &B) +{ + iq1 C; + C.val = A.val ^ B; + return(C); +} + +inline iq1 & +iq1::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +inline iq +operator^(const iq &A, const long &B) +{ + iq C; + C.val = A.val ^ B; + return(C); +} + +inline iq & +iq::operator^=(const long &A) +{ + val ^= A; + return(*this); +} + +//***************************************************************************** +// +// Otherwise, floating point math is being used. +// +//***************************************************************************** +#else // MATH_TYPE == FLOAT_MATH + +//***************************************************************************** +// +// The floating point equivalent of the various IQ formats. +// +//***************************************************************************** +typedef float iq30; +typedef float iq29; +typedef float iq28; +typedef float iq27; +typedef float iq26; +typedef float iq25; +typedef float iq24; +typedef float iq23; +typedef float iq22; +typedef float iq21; +typedef float iq20; +typedef float iq19; +typedef float iq18; +typedef float iq17; +typedef float iq16; +typedef float iq15; +typedef float iq14; +typedef float iq13; +typedef float iq12; +typedef float iq11; +typedef float iq10; +typedef float iq9; +typedef float iq8; +typedef float iq7; +typedef float iq6; +typedef float iq5; +typedef float iq4; +typedef float iq3; +typedef float iq2; +typedef float iq1; +typedef float iq; + +//***************************************************************************** +// +// Convert a value into an IQ number. +// +//***************************************************************************** +#define IQ30(A) (A) +#define IQ29(A) (A) +#define IQ28(A) (A) +#define IQ27(A) (A) +#define IQ26(A) (A) +#define IQ25(A) (A) +#define IQ24(A) (A) +#define IQ23(A) (A) +#define IQ22(A) (A) +#define IQ21(A) (A) +#define IQ20(A) (A) +#define IQ19(A) (A) +#define IQ18(A) (A) +#define IQ17(A) (A) +#define IQ16(A) (A) +#define IQ15(A) (A) +#define IQ14(A) (A) +#define IQ13(A) (A) +#define IQ12(A) (A) +#define IQ11(A) (A) +#define IQ10(A) (A) +#define IQ9(A) (A) +#define IQ8(A) (A) +#define IQ7(A) (A) +#define IQ6(A) (A) +#define IQ5(A) (A) +#define IQ4(A) (A) +#define IQ3(A) (A) +#define IQ2(A) (A) +#define IQ1(A) (A) +#define IQ(A) (A) + +//***************************************************************************** +// +// Convert an IQ number to a floating point value. +// +//***************************************************************************** +#define IQ30toF(A) (A) +#define IQ29toF(A) (A) +#define IQ28toF(A) (A) +#define IQ27toF(A) (A) +#define IQ26toF(A) (A) +#define IQ25toF(A) (A) +#define IQ24toF(A) (A) +#define IQ23toF(A) (A) +#define IQ22toF(A) (A) +#define IQ21toF(A) (A) +#define IQ20toF(A) (A) +#define IQ19toF(A) (A) +#define IQ18toF(A) (A) +#define IQ17toF(A) (A) +#define IQ16toF(A) (A) +#define IQ15toF(A) (A) +#define IQ14toF(A) (A) +#define IQ13toF(A) (A) +#define IQ12toF(A) (A) +#define IQ11toF(A) (A) +#define IQ10toF(A) (A) +#define IQ9toF(A) (A) +#define IQ8toF(A) (A) +#define IQ7toF(A) (A) +#define IQ6toF(A) (A) +#define IQ5toF(A) (A) +#define IQ4toF(A) (A) +#define IQ3toF(A) (A) +#define IQ2toF(A) (A) +#define IQ1toF(A) (A) +#define IQtoF(A) (A) + +//***************************************************************************** +// +// Convert an IQ number to a double-precision floating point value. +// +//***************************************************************************** +#define IQ30toD(A) (A) +#define IQ29toD(A) (A) +#define IQ28toD(A) (A) +#define IQ27toD(A) (A) +#define IQ26toD(A) (A) +#define IQ25toD(A) (A) +#define IQ24toD(A) (A) +#define IQ23toD(A) (A) +#define IQ22toD(A) (A) +#define IQ21toD(A) (A) +#define IQ20toD(A) (A) +#define IQ19toD(A) (A) +#define IQ18toD(A) (A) +#define IQ17toD(A) (A) +#define IQ16toD(A) (A) +#define IQ15toD(A) (A) +#define IQ14toD(A) (A) +#define IQ13toD(A) (A) +#define IQ12toD(A) (A) +#define IQ11toD(A) (A) +#define IQ10toD(A) (A) +#define IQ9toD(A) (A) +#define IQ8toD(A) (A) +#define IQ7toD(A) (A) +#define IQ6toD(A) (A) +#define IQ5toD(A) (A) +#define IQ4toD(A) (A) +#define IQ3toD(A) (A) +#define IQ2toD(A) (A) +#define IQ1toD(A) (A) +#define IQtoD(A) (A) + +//***************************************************************************** +// +// Saturates an IQ number in a given range. +// +//***************************************************************************** +#define IQsat(A, Pos, Neg) _IQsat(A, Pos, Neg) + +//***************************************************************************** +// +// Converts an IQ number between the global IQ format and a specified IQ +// format. +// +//***************************************************************************** +#define IQtoIQ30(A) (A) +#define IQ30toIQ(A) (A) +#define IQtoIQ29(A) (A) +#define IQ29toIQ(A) (A) +#define IQtoIQ28(A) (A) +#define IQ28toIQ(A) (A) +#define IQtoIQ27(A) (A) +#define IQ27toIQ(A) (A) +#define IQtoIQ26(A) (A) +#define IQ26toIQ(A) (A) +#define IQtoIQ25(A) (A) +#define IQ25toIQ(A) (A) +#define IQtoIQ24(A) (A) +#define IQ24toIQ(A) (A) +#define IQtoIQ23(A) (A) +#define IQ23toIQ(A) (A) +#define IQtoIQ22(A) (A) +#define IQ22toIQ(A) (A) +#define IQtoIQ21(A) (A) +#define IQ21toIQ(A) (A) +#define IQtoIQ20(A) (A) +#define IQ20toIQ(A) (A) +#define IQtoIQ19(A) (A) +#define IQ19toIQ(A) (A) +#define IQtoIQ18(A) (A) +#define IQ18toIQ(A) (A) +#define IQtoIQ17(A) (A) +#define IQ17toIQ(A) (A) +#define IQtoIQ16(A) (A) +#define IQ16toIQ(A) (A) +#define IQtoIQ15(A) (A) +#define IQ15toIQ(A) (A) +#define IQtoIQ14(A) (A) +#define IQ14toIQ(A) (A) +#define IQtoIQ13(A) (A) +#define IQ13toIQ(A) (A) +#define IQtoIQ12(A) (A) +#define IQ12toIQ(A) (A) +#define IQtoIQ11(A) (A) +#define IQ11toIQ(A) (A) +#define IQtoIQ10(A) (A) +#define IQ10toIQ(A) (A) +#define IQtoIQ9(A) (A) +#define IQ9toIQ(A) (A) +#define IQtoIQ8(A) (A) +#define IQ8toIQ(A) (A) +#define IQtoIQ7(A) (A) +#define IQ7toIQ(A) (A) +#define IQtoIQ6(A) (A) +#define IQ6toIQ(A) (A) +#define IQtoIQ5(A) (A) +#define IQ5toIQ(A) (A) +#define IQtoIQ4(A) (A) +#define IQ4toIQ(A) (A) +#define IQtoIQ3(A) (A) +#define IQ3toIQ(A) (A) +#define IQtoIQ2(A) (A) +#define IQ2toIQ(A) (A) +#define IQtoIQ1(A) (A) +#define IQ1toIQ(A) (A) + +//***************************************************************************** +// +// Converts a number between IQ format and 16-bit Qn format. +// +//***************************************************************************** +#define IQtoQ15(A) ((short)((long)((A) * (1 << 15)))) +#define Q15toIQ(A) (((float)(A)) * (1.0 / (1 << 15))) +#define IQtoQ14(A) ((short)((long)((A) * (1 << 14)))) +#define Q14toIQ(A) (((float)(A)) * (1.0 / (1 << 14))) +#define IQtoQ13(A) ((short)((long)((A) * (1 << 13)))) +#define Q13toIQ(A) (((float)(A)) * (1.0 / (1 << 13))) +#define IQtoQ12(A) ((short)((long)((A) * (1 << 12)))) +#define Q12toIQ(A) (((float)(A)) * (1.0 / (1 << 12))) +#define IQtoQ11(A) ((short)((long)((A) * (1 << 11)))) +#define Q11toIQ(A) (((float)(A)) * (1.0 / (1 << 11))) +#define IQtoQ10(A) ((short)((long)((A) * (1 << 10)))) +#define Q10toIQ(A) (((float)(A)) * (1.0 / (1 << 10))) +#define IQtoQ9(A) ((short)((long)((A) * (1 << 9)))) +#define Q9toIQ(A) (((float)(A)) * (1.0 / (1 << 9))) +#define IQtoQ8(A) ((short)((long)((A) * (1 << 8)))) +#define Q8toIQ(A) (((float)(A)) * (1.0 / (1 << 8))) +#define IQtoQ7(A) ((short)((long)((A) * (1 << 7)))) +#define Q7toIQ(A) (((float)(A)) * (1.0 / (1 << 7))) +#define IQtoQ6(A) ((short)((long)((A) * (1 << 6)))) +#define Q6toIQ(A) (((float)(A)) * (1.0 / (1 << 6))) +#define IQtoQ5(A) ((short)((long)((A) * (1 << 5)))) +#define Q5toIQ(A) (((float)(A)) * (1.0 / (1 << 5))) +#define IQtoQ4(A) ((short)((long)((A) * (1 << 4)))) +#define Q4toIQ(A) (((float)(A)) * (1.0 / (1 << 4))) +#define IQtoQ3(A) ((short)((long)((A) * (1 << 3)))) +#define Q3toIQ(A) (((float)(A)) * (1.0 / (1 << 3))) +#define IQtoQ2(A) ((short)((long)((A) * (1 << 2)))) +#define Q2toIQ(A) (((float)(A)) * (1.0 / (1 << 2))) +#define IQtoQ1(A) ((short)((long)((A) * (1 << 1)))) +#define Q1toIQ(A) (((float)(A)) * (1.0 / (1 << 1))) + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding. +// +//***************************************************************************** +#define IQ30rmpy(A, B) ((A) * (B)) +#define IQ29rmpy(A, B) ((A) * (B)) +#define IQ28rmpy(A, B) ((A) * (B)) +#define IQ27rmpy(A, B) ((A) * (B)) +#define IQ26rmpy(A, B) ((A) * (B)) +#define IQ25rmpy(A, B) ((A) * (B)) +#define IQ24rmpy(A, B) ((A) * (B)) +#define IQ23rmpy(A, B) ((A) * (B)) +#define IQ22rmpy(A, B) ((A) * (B)) +#define IQ21rmpy(A, B) ((A) * (B)) +#define IQ20rmpy(A, B) ((A) * (B)) +#define IQ19rmpy(A, B) ((A) * (B)) +#define IQ18rmpy(A, B) ((A) * (B)) +#define IQ17rmpy(A, B) ((A) * (B)) +#define IQ16rmpy(A, B) ((A) * (B)) +#define IQ15rmpy(A, B) ((A) * (B)) +#define IQ14rmpy(A, B) ((A) * (B)) +#define IQ13rmpy(A, B) ((A) * (B)) +#define IQ12rmpy(A, B) ((A) * (B)) +#define IQ11rmpy(A, B) ((A) * (B)) +#define IQ10rmpy(A, B) ((A) * (B)) +#define IQ9rmpy(A, B) ((A) * (B)) +#define IQ8rmpy(A, B) ((A) * (B)) +#define IQ7rmpy(A, B) ((A) * (B)) +#define IQ6rmpy(A, B) ((A) * (B)) +#define IQ5rmpy(A, B) ((A) * (B)) +#define IQ4rmpy(A, B) ((A) * (B)) +#define IQ3rmpy(A, B) ((A) * (B)) +#define IQ2rmpy(A, B) ((A) * (B)) +#define IQ1rmpy(A, B) ((A) * (B)) +#define IQrmpy(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding and saturation. +// +//***************************************************************************** +#define IQ30rsmpy(A, B) ((A) * (B)) +#define IQ29rsmpy(A, B) ((A) * (B)) +#define IQ28rsmpy(A, B) ((A) * (B)) +#define IQ27rsmpy(A, B) ((A) * (B)) +#define IQ26rsmpy(A, B) ((A) * (B)) +#define IQ25rsmpy(A, B) ((A) * (B)) +#define IQ24rsmpy(A, B) ((A) * (B)) +#define IQ23rsmpy(A, B) ((A) * (B)) +#define IQ22rsmpy(A, B) ((A) * (B)) +#define IQ21rsmpy(A, B) ((A) * (B)) +#define IQ20rsmpy(A, B) ((A) * (B)) +#define IQ19rsmpy(A, B) ((A) * (B)) +#define IQ18rsmpy(A, B) ((A) * (B)) +#define IQ17rsmpy(A, B) ((A) * (B)) +#define IQ16rsmpy(A, B) ((A) * (B)) +#define IQ15rsmpy(A, B) ((A) * (B)) +#define IQ14rsmpy(A, B) ((A) * (B)) +#define IQ13rsmpy(A, B) ((A) * (B)) +#define IQ12rsmpy(A, B) ((A) * (B)) +#define IQ11rsmpy(A, B) ((A) * (B)) +#define IQ10rsmpy(A, B) ((A) * (B)) +#define IQ9rsmpy(A, B) ((A) * (B)) +#define IQ8rsmpy(A, B) ((A) * (B)) +#define IQ7rsmpy(A, B) ((A) * (B)) +#define IQ6rsmpy(A, B) ((A) * (B)) +#define IQ5rsmpy(A, B) ((A) * (B)) +#define IQ4rsmpy(A, B) ((A) * (B)) +#define IQ3rsmpy(A, B) ((A) * (B)) +#define IQ2rsmpy(A, B) ((A) * (B)) +#define IQ1rsmpy(A, B) ((A) * (B)) +#define IQrsmpy(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Computes the sin of an IQ number. +// +//***************************************************************************** +#define IQ29sin(A) sin(A) +#define IQ28sin(A) sin(A) +#define IQ27sin(A) sin(A) +#define IQ26sin(A) sin(A) +#define IQ25sin(A) sin(A) +#define IQ24sin(A) sin(A) +#define IQ23sin(A) sin(A) +#define IQ22sin(A) sin(A) +#define IQ21sin(A) sin(A) +#define IQ20sin(A) sin(A) +#define IQ19sin(A) sin(A) +#define IQ18sin(A) sin(A) +#define IQ17sin(A) sin(A) +#define IQ16sin(A) sin(A) +#define IQ15sin(A) sin(A) +#define IQ14sin(A) sin(A) +#define IQ13sin(A) sin(A) +#define IQ12sin(A) sin(A) +#define IQ11sin(A) sin(A) +#define IQ10sin(A) sin(A) +#define IQ9sin(A) sin(A) +#define IQ8sin(A) sin(A) +#define IQ7sin(A) sin(A) +#define IQ6sin(A) sin(A) +#define IQ5sin(A) sin(A) +#define IQ4sin(A) sin(A) +#define IQ3sin(A) sin(A) +#define IQ2sin(A) sin(A) +#define IQ1sin(A) sin(A) +#define IQsin(A) sin(A) + +//***************************************************************************** +// +// Computes the sin of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +#define IQ30sinPU(A) sin((A) * 6.283185307) +#define IQ29sinPU(A) sin((A) * 6.283185307) +#define IQ28sinPU(A) sin((A) * 6.283185307) +#define IQ27sinPU(A) sin((A) * 6.283185307) +#define IQ26sinPU(A) sin((A) * 6.283185307) +#define IQ25sinPU(A) sin((A) * 6.283185307) +#define IQ24sinPU(A) sin((A) * 6.283185307) +#define IQ23sinPU(A) sin((A) * 6.283185307) +#define IQ22sinPU(A) sin((A) * 6.283185307) +#define IQ21sinPU(A) sin((A) * 6.283185307) +#define IQ20sinPU(A) sin((A) * 6.283185307) +#define IQ19sinPU(A) sin((A) * 6.283185307) +#define IQ18sinPU(A) sin((A) * 6.283185307) +#define IQ17sinPU(A) sin((A) * 6.283185307) +#define IQ16sinPU(A) sin((A) * 6.283185307) +#define IQ15sinPU(A) sin((A) * 6.283185307) +#define IQ14sinPU(A) sin((A) * 6.283185307) +#define IQ13sinPU(A) sin((A) * 6.283185307) +#define IQ12sinPU(A) sin((A) * 6.283185307) +#define IQ11sinPU(A) sin((A) * 6.283185307) +#define IQ10sinPU(A) sin((A) * 6.283185307) +#define IQ9sinPU(A) sin((A) * 6.283185307) +#define IQ8sinPU(A) sin((A) * 6.283185307) +#define IQ7sinPU(A) sin((A) * 6.283185307) +#define IQ6sinPU(A) sin((A) * 6.283185307) +#define IQ5sinPU(A) sin((A) * 6.283185307) +#define IQ4sinPU(A) sin((A) * 6.283185307) +#define IQ3sinPU(A) sin((A) * 6.283185307) +#define IQ2sinPU(A) sin((A) * 6.283185307) +#define IQ1sinPU(A) sin((A) * 6.283185307) +#define IQsinPU(A) sin((A) * 6.283185307) + +//***************************************************************************** +// +// Computes the arcsin of an IQ number. +// +//***************************************************************************** +#define IQ29asin(A) asin(A) +#define IQ28asin(A) asin(A) +#define IQ27asin(A) asin(A) +#define IQ26asin(A) asin(A) +#define IQ25asin(A) asin(A) +#define IQ24asin(A) asin(A) +#define IQ23asin(A) asin(A) +#define IQ22asin(A) asin(A) +#define IQ21asin(A) asin(A) +#define IQ20asin(A) asin(A) +#define IQ19asin(A) asin(A) +#define IQ18asin(A) asin(A) +#define IQ17asin(A) asin(A) +#define IQ16asin(A) asin(A) +#define IQ15asin(A) asin(A) +#define IQ14asin(A) asin(A) +#define IQ13asin(A) asin(A) +#define IQ12asin(A) asin(A) +#define IQ11asin(A) asin(A) +#define IQ10asin(A) asin(A) +#define IQ9asin(A) asin(A) +#define IQ8asin(A) asin(A) +#define IQ7asin(A) asin(A) +#define IQ6asin(A) asin(A) +#define IQ5asin(A) asin(A) +#define IQ4asin(A) asin(A) +#define IQ3asin(A) asin(A) +#define IQ2asin(A) asin(A) +#define IQ1asin(A) asin(A) +#define IQasin(A) asin(A) + +//***************************************************************************** +// +// Computes the cos of an IQ number. +// +//***************************************************************************** +#define IQ29cos(A) cos(A) +#define IQ28cos(A) cos(A) +#define IQ27cos(A) cos(A) +#define IQ26cos(A) cos(A) +#define IQ25cos(A) cos(A) +#define IQ24cos(A) cos(A) +#define IQ23cos(A) cos(A) +#define IQ22cos(A) cos(A) +#define IQ21cos(A) cos(A) +#define IQ20cos(A) cos(A) +#define IQ19cos(A) cos(A) +#define IQ18cos(A) cos(A) +#define IQ17cos(A) cos(A) +#define IQ16cos(A) cos(A) +#define IQ15cos(A) cos(A) +#define IQ14cos(A) cos(A) +#define IQ13cos(A) cos(A) +#define IQ12cos(A) cos(A) +#define IQ11cos(A) cos(A) +#define IQ10cos(A) cos(A) +#define IQ9cos(A) cos(A) +#define IQ8cos(A) cos(A) +#define IQ7cos(A) cos(A) +#define IQ6cos(A) cos(A) +#define IQ5cos(A) cos(A) +#define IQ4cos(A) cos(A) +#define IQ3cos(A) cos(A) +#define IQ2cos(A) cos(A) +#define IQ1cos(A) cos(A) +#define IQcos(A) cos(A) + +//***************************************************************************** +// +// Computes the cos of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +#define IQ30cosPU(A) cos((A) * 6.283185307) +#define IQ29cosPU(A) cos((A) * 6.283185307) +#define IQ28cosPU(A) cos((A) * 6.283185307) +#define IQ27cosPU(A) cos((A) * 6.283185307) +#define IQ26cosPU(A) cos((A) * 6.283185307) +#define IQ25cosPU(A) cos((A) * 6.283185307) +#define IQ24cosPU(A) cos((A) * 6.283185307) +#define IQ23cosPU(A) cos((A) * 6.283185307) +#define IQ22cosPU(A) cos((A) * 6.283185307) +#define IQ21cosPU(A) cos((A) * 6.283185307) +#define IQ20cosPU(A) cos((A) * 6.283185307) +#define IQ19cosPU(A) cos((A) * 6.283185307) +#define IQ18cosPU(A) cos((A) * 6.283185307) +#define IQ17cosPU(A) cos((A) * 6.283185307) +#define IQ16cosPU(A) cos((A) * 6.283185307) +#define IQ15cosPU(A) cos((A) * 6.283185307) +#define IQ14cosPU(A) cos((A) * 6.283185307) +#define IQ13cosPU(A) cos((A) * 6.283185307) +#define IQ12cosPU(A) cos((A) * 6.283185307) +#define IQ11cosPU(A) cos((A) * 6.283185307) +#define IQ10cosPU(A) cos((A) * 6.283185307) +#define IQ9cosPU(A) cos((A) * 6.283185307) +#define IQ8cosPU(A) cos((A) * 6.283185307) +#define IQ7cosPU(A) cos((A) * 6.283185307) +#define IQ6cosPU(A) cos((A) * 6.283185307) +#define IQ5cosPU(A) cos((A) * 6.283185307) +#define IQ4cosPU(A) cos((A) * 6.283185307) +#define IQ3cosPU(A) cos((A) * 6.283185307) +#define IQ2cosPU(A) cos((A) * 6.283185307) +#define IQ1cosPU(A) cos((A) * 6.283185307) +#define IQcosPU(A) cos((A) * 6.283185307) + +//***************************************************************************** +// +// Computes the arccos of an IQ number. +// +//***************************************************************************** +#define IQ29acos(A) acos(A) +#define IQ28acos(A) acos(A) +#define IQ27acos(A) acos(A) +#define IQ26acos(A) acos(A) +#define IQ25acos(A) acos(A) +#define IQ24acos(A) acos(A) +#define IQ23acos(A) acos(A) +#define IQ22acos(A) acos(A) +#define IQ21acos(A) acos(A) +#define IQ20acos(A) acos(A) +#define IQ19acos(A) acos(A) +#define IQ18acos(A) acos(A) +#define IQ17acos(A) acos(A) +#define IQ16acos(A) acos(A) +#define IQ15acos(A) acos(A) +#define IQ14acos(A) acos(A) +#define IQ13acos(A) acos(A) +#define IQ12acos(A) acos(A) +#define IQ11acos(A) acos(A) +#define IQ10acos(A) acos(A) +#define IQ9acos(A) acos(A) +#define IQ8acos(A) acos(A) +#define IQ7acos(A) acos(A) +#define IQ6acos(A) acos(A) +#define IQ5acos(A) acos(A) +#define IQ4acos(A) acos(A) +#define IQ3acos(A) acos(A) +#define IQ2acos(A) acos(A) +#define IQ1acos(A) acos(A) +#define IQacos(A) acos(A) + +//***************************************************************************** +// +// Computes the arctan of an IQ number. +// +//***************************************************************************** +#define IQ29atan(A) atan(A) +#define IQ28atan(A) atan(A) +#define IQ27atan(A) atan(A) +#define IQ26atan(A) atan(A) +#define IQ25atan(A) atan(A) +#define IQ24atan(A) atan(A) +#define IQ23atan(A) atan(A) +#define IQ22atan(A) atan(A) +#define IQ21atan(A) atan(A) +#define IQ20atan(A) atan(A) +#define IQ19atan(A) atan(A) +#define IQ18atan(A) atan(A) +#define IQ17atan(A) atan(A) +#define IQ16atan(A) atan(A) +#define IQ15atan(A) atan(A) +#define IQ14atan(A) atan(A) +#define IQ13atan(A) atan(A) +#define IQ12atan(A) atan(A) +#define IQ11atan(A) atan(A) +#define IQ10atan(A) atan(A) +#define IQ9atan(A) atan(A) +#define IQ8atan(A) atan(A) +#define IQ7atan(A) atan(A) +#define IQ6atan(A) atan(A) +#define IQ5atan(A) atan(A) +#define IQ4atan(A) atan(A) +#define IQ3atan(A) atan(A) +#define IQ2atan(A) atan(A) +#define IQ1atan(A) atan(A) +#define IQatan(A) atan(A) + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers. +// +//***************************************************************************** +#define IQ30atan2(A, B) atan2(A, B) +#define IQ29atan2(A, B) atan2(A, B) +#define IQ28atan2(A, B) atan2(A, B) +#define IQ27atan2(A, B) atan2(A, B) +#define IQ26atan2(A, B) atan2(A, B) +#define IQ25atan2(A, B) atan2(A, B) +#define IQ24atan2(A, B) atan2(A, B) +#define IQ23atan2(A, B) atan2(A, B) +#define IQ22atan2(A, B) atan2(A, B) +#define IQ21atan2(A, B) atan2(A, B) +#define IQ20atan2(A, B) atan2(A, B) +#define IQ19atan2(A, B) atan2(A, B) +#define IQ18atan2(A, B) atan2(A, B) +#define IQ17atan2(A, B) atan2(A, B) +#define IQ16atan2(A, B) atan2(A, B) +#define IQ15atan2(A, B) atan2(A, B) +#define IQ14atan2(A, B) atan2(A, B) +#define IQ13atan2(A, B) atan2(A, B) +#define IQ12atan2(A, B) atan2(A, B) +#define IQ11atan2(A, B) atan2(A, B) +#define IQ10atan2(A, B) atan2(A, B) +#define IQ9atan2(A, B) atan2(A, B) +#define IQ8atan2(A, B) atan2(A, B) +#define IQ7atan2(A, B) atan2(A, B) +#define IQ6atan2(A, B) atan2(A, B) +#define IQ5atan2(A, B) atan2(A, B) +#define IQ4atan2(A, B) atan2(A, B) +#define IQ3atan2(A, B) atan2(A, B) +#define IQ2atan2(A, B) atan2(A, B) +#define IQ1atan2(A, B) atan2(A, B) +#define IQatan2(A, B) atan2(A, B) + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers, returning +// the value in cycles per unit instead of radians. +// +//***************************************************************************** +#define IQ30atan2PU(A, B) _IQ30atan2PU(A, B) +#define IQ29atan2PU(A, B) _IQ29atan2PU(A, B) +#define IQ28atan2PU(A, B) _IQ28atan2PU(A, B) +#define IQ27atan2PU(A, B) _IQ27atan2PU(A, B) +#define IQ26atan2PU(A, B) _IQ26atan2PU(A, B) +#define IQ25atan2PU(A, B) _IQ25atan2PU(A, B) +#define IQ24atan2PU(A, B) _IQ24atan2PU(A, B) +#define IQ23atan2PU(A, B) _IQ23atan2PU(A, B) +#define IQ22atan2PU(A, B) _IQ22atan2PU(A, B) +#define IQ21atan2PU(A, B) _IQ21atan2PU(A, B) +#define IQ20atan2PU(A, B) _IQ20atan2PU(A, B) +#define IQ19atan2PU(A, B) _IQ19atan2PU(A, B) +#define IQ18atan2PU(A, B) _IQ18atan2PU(A, B) +#define IQ17atan2PU(A, B) _IQ17atan2PU(A, B) +#define IQ16atan2PU(A, B) _IQ16atan2PU(A, B) +#define IQ15atan2PU(A, B) _IQ15atan2PU(A, B) +#define IQ14atan2PU(A, B) _IQ14atan2PU(A, B) +#define IQ13atan2PU(A, B) _IQ13atan2PU(A, B) +#define IQ12atan2PU(A, B) _IQ12atan2PU(A, B) +#define IQ11atan2PU(A, B) _IQ11atan2PU(A, B) +#define IQ10atan2PU(A, B) _IQ10atan2PU(A, B) +#define IQ9atan2PU(A, B) _IQ9atan2PU(A, B) +#define IQ8atan2PU(A, B) _IQ8atan2PU(A, B) +#define IQ7atan2PU(A, B) _IQ7atan2PU(A, B) +#define IQ6atan2PU(A, B) _IQ6atan2PU(A, B) +#define IQ5atan2PU(A, B) _IQ5atan2PU(A, B) +#define IQ4atan2PU(A, B) _IQ4atan2PU(A, B) +#define IQ3atan2PU(A, B) _IQ3atan2PU(A, B) +#define IQ2atan2PU(A, B) _IQ2atan2PU(A, B) +#define IQ1atan2PU(A, B) _IQ1atan2PU(A, B) +#define IQatan2PU(A, B) _IQ_QQ_atan2PU(A, B) + +//***************************************************************************** +// +// Computes the square root of an IQ number. +// +//***************************************************************************** +#define IQ30sqrt(A) sqrt(A) +#define IQ29sqrt(A) sqrt(A) +#define IQ28sqrt(A) sqrt(A) +#define IQ27sqrt(A) sqrt(A) +#define IQ26sqrt(A) sqrt(A) +#define IQ25sqrt(A) sqrt(A) +#define IQ24sqrt(A) sqrt(A) +#define IQ23sqrt(A) sqrt(A) +#define IQ22sqrt(A) sqrt(A) +#define IQ21sqrt(A) sqrt(A) +#define IQ20sqrt(A) sqrt(A) +#define IQ19sqrt(A) sqrt(A) +#define IQ18sqrt(A) sqrt(A) +#define IQ17sqrt(A) sqrt(A) +#define IQ16sqrt(A) sqrt(A) +#define IQ15sqrt(A) sqrt(A) +#define IQ14sqrt(A) sqrt(A) +#define IQ13sqrt(A) sqrt(A) +#define IQ12sqrt(A) sqrt(A) +#define IQ11sqrt(A) sqrt(A) +#define IQ10sqrt(A) sqrt(A) +#define IQ9sqrt(A) sqrt(A) +#define IQ8sqrt(A) sqrt(A) +#define IQ7sqrt(A) sqrt(A) +#define IQ6sqrt(A) sqrt(A) +#define IQ5sqrt(A) sqrt(A) +#define IQ4sqrt(A) sqrt(A) +#define IQ3sqrt(A) sqrt(A) +#define IQ2sqrt(A) sqrt(A) +#define IQ1sqrt(A) sqrt(A) +#define IQsqrt(A) sqrt(A) + +//***************************************************************************** +// +// Computes 1 over the square root of an IQ number. +// +//***************************************************************************** +#define IQ30isqrt(A) (1.0 / sqrt(A)) +#define IQ29isqrt(A) (1.0 / sqrt(A)) +#define IQ28isqrt(A) (1.0 / sqrt(A)) +#define IQ27isqrt(A) (1.0 / sqrt(A)) +#define IQ26isqrt(A) (1.0 / sqrt(A)) +#define IQ25isqrt(A) (1.0 / sqrt(A)) +#define IQ24isqrt(A) (1.0 / sqrt(A)) +#define IQ23isqrt(A) (1.0 / sqrt(A)) +#define IQ22isqrt(A) (1.0 / sqrt(A)) +#define IQ21isqrt(A) (1.0 / sqrt(A)) +#define IQ20isqrt(A) (1.0 / sqrt(A)) +#define IQ19isqrt(A) (1.0 / sqrt(A)) +#define IQ18isqrt(A) (1.0 / sqrt(A)) +#define IQ17isqrt(A) (1.0 / sqrt(A)) +#define IQ16isqrt(A) (1.0 / sqrt(A)) +#define IQ15isqrt(A) (1.0 / sqrt(A)) +#define IQ14isqrt(A) (1.0 / sqrt(A)) +#define IQ13isqrt(A) (1.0 / sqrt(A)) +#define IQ12isqrt(A) (1.0 / sqrt(A)) +#define IQ11isqrt(A) (1.0 / sqrt(A)) +#define IQ10isqrt(A) (1.0 / sqrt(A)) +#define IQ9isqrt(A) (1.0 / sqrt(A)) +#define IQ8isqrt(A) (1.0 / sqrt(A)) +#define IQ7isqrt(A) (1.0 / sqrt(A)) +#define IQ6isqrt(A) (1.0 / sqrt(A)) +#define IQ5isqrt(A) (1.0 / sqrt(A)) +#define IQ4isqrt(A) (1.0 / sqrt(A)) +#define IQ3isqrt(A) (1.0 / sqrt(A)) +#define IQ2isqrt(A) (1.0 / sqrt(A)) +#define IQ1isqrt(A) (1.0 / sqrt(A)) +#define IQisqrt(A) (1.0 / sqrt(A)) + +//***************************************************************************** +// +// Computes e^x of an IQ number. +// +//***************************************************************************** +#define IQ30exp(A) exp(A) +#define IQ29exp(A) exp(A) +#define IQ28exp(A) exp(A) +#define IQ27exp(A) exp(A) +#define IQ26exp(A) exp(A) +#define IQ25exp(A) exp(A) +#define IQ24exp(A) exp(A) +#define IQ23exp(A) exp(A) +#define IQ22exp(A) exp(A) +#define IQ21exp(A) exp(A) +#define IQ20exp(A) exp(A) +#define IQ19exp(A) exp(A) +#define IQ18exp(A) exp(A) +#define IQ17exp(A) exp(A) +#define IQ16exp(A) exp(A) +#define IQ15exp(A) exp(A) +#define IQ14exp(A) exp(A) +#define IQ13exp(A) exp(A) +#define IQ12exp(A) exp(A) +#define IQ11exp(A) exp(A) +#define IQ10exp(A) exp(A) +#define IQ9exp(A) exp(A) +#define IQ8exp(A) exp(A) +#define IQ7exp(A) exp(A) +#define IQ6exp(A) exp(A) +#define IQ5exp(A) exp(A) +#define IQ4exp(A) exp(A) +#define IQ3exp(A) exp(A) +#define IQ2exp(A) exp(A) +#define IQ1exp(A) exp(A) +#define IQexp(A) exp(A) + +//***************************************************************************** +// +// Computes 2^x of an IQ number. +// +//***************************************************************************** +#define IQ30exp2(A) exp2(A) +#define IQ29exp2(A) exp2(A) +#define IQ28exp2(A) exp2(A) +#define IQ27exp2(A) exp2(A) +#define IQ26exp2(A) exp2(A) +#define IQ25exp2(A) exp2(A) +#define IQ24exp2(A) exp2(A) +#define IQ23exp2(A) exp2(A) +#define IQ22exp2(A) exp2(A) +#define IQ21exp2(A) exp2(A) +#define IQ20exp2(A) exp2(A) +#define IQ19exp2(A) exp2(A) +#define IQ18exp2(A) exp2(A) +#define IQ17exp2(A) exp2(A) +#define IQ16exp2(A) exp2(A) +#define IQ15exp2(A) exp2(A) +#define IQ14exp2(A) exp2(A) +#define IQ13exp2(A) exp2(A) +#define IQ12exp2(A) exp2(A) +#define IQ11exp2(A) exp2(A) +#define IQ10exp2(A) exp2(A) +#define IQ9exp2(A) exp2(A) +#define IQ8exp2(A) exp2(A) +#define IQ7exp2(A) exp2(A) +#define IQ6exp2(A) exp2(A) +#define IQ5exp2(A) exp2(A) +#define IQ4exp2(A) exp2(A) +#define IQ3exp2(A) exp2(A) +#define IQ2exp2(A) exp2(A) +#define IQ1exp2(A) exp2(A) +#define IQexp2(A) exp2(A) + +//***************************************************************************** +// +// Returns the integer portion of an IQ number. +// +//***************************************************************************** +#define IQ30int(A) ((long)(A)) +#define IQ29int(A) ((long)(A)) +#define IQ28int(A) ((long)(A)) +#define IQ27int(A) ((long)(A)) +#define IQ26int(A) ((long)(A)) +#define IQ25int(A) ((long)(A)) +#define IQ24int(A) ((long)(A)) +#define IQ23int(A) ((long)(A)) +#define IQ22int(A) ((long)(A)) +#define IQ21int(A) ((long)(A)) +#define IQ20int(A) ((long)(A)) +#define IQ19int(A) ((long)(A)) +#define IQ18int(A) ((long)(A)) +#define IQ17int(A) ((long)(A)) +#define IQ16int(A) ((long)(A)) +#define IQ15int(A) ((long)(A)) +#define IQ14int(A) ((long)(A)) +#define IQ13int(A) ((long)(A)) +#define IQ12int(A) ((long)(A)) +#define IQ11int(A) ((long)(A)) +#define IQ10int(A) ((long)(A)) +#define IQ9int(A) ((long)(A)) +#define IQ8int(A) ((long)(A)) +#define IQ7int(A) ((long)(A)) +#define IQ6int(A) ((long)(A)) +#define IQ5int(A) ((long)(A)) +#define IQ4int(A) ((long)(A)) +#define IQ3int(A) ((long)(A)) +#define IQ2int(A) ((long)(A)) +#define IQ1int(A) ((long)(A)) +#define IQint(A) ((long)(A)) + +//***************************************************************************** +// +// Computes the fractional portion of an IQ number. +// +//***************************************************************************** +#define IQ30frac(A) ((A) - (float)((long)(A))) +#define IQ29frac(A) ((A) - (float)((long)(A))) +#define IQ28frac(A) ((A) - (float)((long)(A))) +#define IQ27frac(A) ((A) - (float)((long)(A))) +#define IQ26frac(A) ((A) - (float)((long)(A))) +#define IQ25frac(A) ((A) - (float)((long)(A))) +#define IQ24frac(A) ((A) - (float)((long)(A))) +#define IQ23frac(A) ((A) - (float)((long)(A))) +#define IQ22frac(A) ((A) - (float)((long)(A))) +#define IQ21frac(A) ((A) - (float)((long)(A))) +#define IQ20frac(A) ((A) - (float)((long)(A))) +#define IQ19frac(A) ((A) - (float)((long)(A))) +#define IQ18frac(A) ((A) - (float)((long)(A))) +#define IQ17frac(A) ((A) - (float)((long)(A))) +#define IQ16frac(A) ((A) - (float)((long)(A))) +#define IQ15frac(A) ((A) - (float)((long)(A))) +#define IQ14frac(A) ((A) - (float)((long)(A))) +#define IQ13frac(A) ((A) - (float)((long)(A))) +#define IQ12frac(A) ((A) - (float)((long)(A))) +#define IQ11frac(A) ((A) - (float)((long)(A))) +#define IQ10frac(A) ((A) - (float)((long)(A))) +#define IQ9frac(A) ((A) - (float)((long)(A))) +#define IQ8frac(A) ((A) - (float)((long)(A))) +#define IQ7frac(A) ((A) - (float)((long)(A))) +#define IQ6frac(A) ((A) - (float)((long)(A))) +#define IQ5frac(A) ((A) - (float)((long)(A))) +#define IQ4frac(A) ((A) - (float)((long)(A))) +#define IQ3frac(A) ((A) - (float)((long)(A))) +#define IQ2frac(A) ((A) - (float)((long)(A))) +#define IQ1frac(A) ((A) - (float)((long)(A))) +#define IQfrac(A) ((A) - (float)((long)(A))) + +//***************************************************************************** +// +// Multiplies two IQ numbers in the specified IQ formats, returning the result +// in another IQ format. +// +//***************************************************************************** +#define IQ30mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ29mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ28mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ27mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ26mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ25mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ24mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ23mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ22mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ21mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ20mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ19mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ18mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ17mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ16mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ15mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ14mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ13mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ12mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ11mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ10mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ9mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ8mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ7mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ6mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ5mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ4mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ3mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ2mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQ1mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define IQmpyIQX(A, IQA, B, IQB) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer. +// +//***************************************************************************** +#define IQ30mpyI32(A, B) ((A) * (float)(B)) +#define IQ29mpyI32(A, B) ((A) * (float)(B)) +#define IQ28mpyI32(A, B) ((A) * (float)(B)) +#define IQ27mpyI32(A, B) ((A) * (float)(B)) +#define IQ26mpyI32(A, B) ((A) * (float)(B)) +#define IQ25mpyI32(A, B) ((A) * (float)(B)) +#define IQ24mpyI32(A, B) ((A) * (float)(B)) +#define IQ23mpyI32(A, B) ((A) * (float)(B)) +#define IQ22mpyI32(A, B) ((A) * (float)(B)) +#define IQ21mpyI32(A, B) ((A) * (float)(B)) +#define IQ20mpyI32(A, B) ((A) * (float)(B)) +#define IQ19mpyI32(A, B) ((A) * (float)(B)) +#define IQ18mpyI32(A, B) ((A) * (float)(B)) +#define IQ17mpyI32(A, B) ((A) * (float)(B)) +#define IQ16mpyI32(A, B) ((A) * (float)(B)) +#define IQ15mpyI32(A, B) ((A) * (float)(B)) +#define IQ14mpyI32(A, B) ((A) * (float)(B)) +#define IQ13mpyI32(A, B) ((A) * (float)(B)) +#define IQ12mpyI32(A, B) ((A) * (float)(B)) +#define IQ11mpyI32(A, B) ((A) * (float)(B)) +#define IQ10mpyI32(A, B) ((A) * (float)(B)) +#define IQ9mpyI32(A, B) ((A) * (float)(B)) +#define IQ8mpyI32(A, B) ((A) * (float)(B)) +#define IQ7mpyI32(A, B) ((A) * (float)(B)) +#define IQ6mpyI32(A, B) ((A) * (float)(B)) +#define IQ5mpyI32(A, B) ((A) * (float)(B)) +#define IQ4mpyI32(A, B) ((A) * (float)(B)) +#define IQ3mpyI32(A, B) ((A) * (float)(B)) +#define IQ2mpyI32(A, B) ((A) * (float)(B)) +#define IQ1mpyI32(A, B) ((A) * (float)(B)) +#define IQmpyI32(A, B) ((A) * (float)(B)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the integer portion. +// +//***************************************************************************** +#define IQ30mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ29mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ28mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ27mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ26mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ25mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ24mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ23mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ22mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ21mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ20mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ19mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ18mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ17mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ16mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ15mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ14mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ13mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ12mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ11mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ10mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ9mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ8mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ7mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ6mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ5mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ4mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ3mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ2mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQ1mpyI32int(A, B) ((long)((A) * (float)(B))) +#define IQmpyI32int(A, B) ((long)((A) * (float)(B))) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the fractional portion. +// +//***************************************************************************** +#define IQ30mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ29mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ28mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ27mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ26mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ25mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ24mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ23mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ22mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ21mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ20mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ19mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ18mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ17mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ16mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ15mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ14mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ13mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ12mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ11mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ10mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ9mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ8mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ7mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ6mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ5mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ4mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ3mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ2mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQ1mpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) +#define IQmpyI32frac(A, B) ((A) - (float)((long)((A) * (float)(B)))) + +//***************************************************************************** +// +// Computes the square root of A^2 + B^2 using IQ numbers. +// +//***************************************************************************** +#define IQ30mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ29mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ28mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ27mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ26mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ25mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ24mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ23mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ22mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ21mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ20mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ19mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ18mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ17mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ16mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ15mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ14mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ13mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ12mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ11mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ10mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ9mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ8mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ7mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ6mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ5mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ4mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ3mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ2mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQ1mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define IQmag(A, B) sqrt(((A) * (A)) + ((B) * (B))) + +//***************************************************************************** +// +// Converts a string into an IQ number. +// +//***************************************************************************** +#define atoIQ30(A) atof(A) +#define atoIQ29(A) atof(A) +#define atoIQ28(A) atof(A) +#define atoIQ27(A) atof(A) +#define atoIQ26(A) atof(A) +#define atoIQ25(A) atof(A) +#define atoIQ24(A) atof(A) +#define atoIQ23(A) atof(A) +#define atoIQ22(A) atof(A) +#define atoIQ21(A) atof(A) +#define atoIQ20(A) atof(A) +#define atoIQ19(A) atof(A) +#define atoIQ18(A) atof(A) +#define atoIQ17(A) atof(A) +#define atoIQ16(A) atof(A) +#define atoIQ15(A) atof(A) +#define atoIQ14(A) atof(A) +#define atoIQ13(A) atof(A) +#define atoIQ12(A) atof(A) +#define atoIQ11(A) atof(A) +#define atoIQ10(A) atof(A) +#define atoIQ9(A) atof(A) +#define atoIQ8(A) atof(A) +#define atoIQ7(A) atof(A) +#define atoIQ6(A) atof(A) +#define atoIQ5(A) atof(A) +#define atoIQ4(A) atof(A) +#define atoIQ3(A) atof(A) +#define atoIQ2(A) atof(A) +#define atoIQ1(A) atof(A) +#define atoIQ(A) atof(A) + +//***************************************************************************** +// +// Converts an IQ number into a string. +// +//***************************************************************************** +#define IQ30toa(A, B, C) sprintf(A, B, C) +#define IQ29toa(A, B, C) sprintf(A, B, C) +#define IQ28toa(A, B, C) sprintf(A, B, C) +#define IQ27toa(A, B, C) sprintf(A, B, C) +#define IQ26toa(A, B, C) sprintf(A, B, C) +#define IQ25toa(A, B, C) sprintf(A, B, C) +#define IQ24toa(A, B, C) sprintf(A, B, C) +#define IQ23toa(A, B, C) sprintf(A, B, C) +#define IQ22toa(A, B, C) sprintf(A, B, C) +#define IQ21toa(A, B, C) sprintf(A, B, C) +#define IQ20toa(A, B, C) sprintf(A, B, C) +#define IQ19toa(A, B, C) sprintf(A, B, C) +#define IQ18toa(A, B, C) sprintf(A, B, C) +#define IQ17toa(A, B, C) sprintf(A, B, C) +#define IQ16toa(A, B, C) sprintf(A, B, C) +#define IQ15toa(A, B, C) sprintf(A, B, C) +#define IQ14toa(A, B, C) sprintf(A, B, C) +#define IQ13toa(A, B, C) sprintf(A, B, C) +#define IQ12toa(A, B, C) sprintf(A, B, C) +#define IQ11toa(A, B, C) sprintf(A, B, C) +#define IQ10toa(A, B, C) sprintf(A, B, C) +#define IQ9toa(A, B, C) sprintf(A, B, C) +#define IQ8toa(A, B, C) sprintf(A, B, C) +#define IQ7toa(A, B, C) sprintf(A, B, C) +#define IQ6toa(A, B, C) sprintf(A, B, C) +#define IQ5toa(A, B, C) sprintf(A, B, C) +#define IQ4toa(A, B, C) sprintf(A, B, C) +#define IQ3toa(A, B, C) sprintf(A, B, C) +#define IQ2toa(A, B, C) sprintf(A, B, C) +#define IQ1toa(A, B, C) sprintf(A, B, C) +#define IQtoa(A, B, C) sprintf(A, B, C) + +//***************************************************************************** +// +// Computes the absolute value of an IQ number. +// +//***************************************************************************** +#define IQ30abs(A) fabs(A) +#define IQ29abs(A) fabs(A) +#define IQ28abs(A) fabs(A) +#define IQ27abs(A) fabs(A) +#define IQ26abs(A) fabs(A) +#define IQ25abs(A) fabs(A) +#define IQ24abs(A) fabs(A) +#define IQ23abs(A) fabs(A) +#define IQ22abs(A) fabs(A) +#define IQ21abs(A) fabs(A) +#define IQ20abs(A) fabs(A) +#define IQ19abs(A) fabs(A) +#define IQ18abs(A) fabs(A) +#define IQ17abs(A) fabs(A) +#define IQ16abs(A) fabs(A) +#define IQ15abs(A) fabs(A) +#define IQ14abs(A) fabs(A) +#define IQ13abs(A) fabs(A) +#define IQ12abs(A) fabs(A) +#define IQ11abs(A) fabs(A) +#define IQ10abs(A) fabs(A) +#define IQ9abs(A) fabs(A) +#define IQ8abs(A) fabs(A) +#define IQ7abs(A) fabs(A) +#define IQ6abs(A) fabs(A) +#define IQ5abs(A) fabs(A) +#define IQ4abs(A) fabs(A) +#define IQ3abs(A) fabs(A) +#define IQ2abs(A) fabs(A) +#define IQ1abs(A) fabs(A) +#define IQabs(A) fabs(A) + +#endif // MATH_TYPE == IQ_MATH + +#endif // __IQMATHCPP_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathLib.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathLib.h new file mode 100644 index 0000000000000000000000000000000000000000..ab70893efe5f01ccb773e52d75120d8489584a95 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/IQmathLib.h @@ -0,0 +1,5210 @@ +//***************************************************************************** +// +// IQmathLib.h - IQmath library C language function definitions. +// +// Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva IQmath Library. +// +//***************************************************************************** + +#ifndef __IQMATHLIB_H__ +#define __IQMATHLIB_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// By redefining MATH_TYPE, all IQmath functions will be replaced by their +// floating point equivalents. +// +//***************************************************************************** +#define FLOAT_MATH 1 +#define IQ_MATH 0 +#ifndef MATH_TYPE +#define MATH_TYPE IQ_MATH +#endif + +//***************************************************************************** +// +// The IQ format to be used when the IQ format is not explicitly specified +// (such as _IQcos instead of _IQ16cos). This value must be between 1 and 30, +// inclusive. +// +//***************************************************************************** +#ifndef GLOBAL_Q +#define GLOBAL_Q 24 +#endif + +//***************************************************************************** +// +// Include some standard headers, as required based on the math type. +// +//***************************************************************************** +#if MATH_TYPE == FLOAT_MATH +#include +#endif +#include +#include + +//***************************************************************************** +// +// Various Useful Constant Definitions: +// +//***************************************************************************** +#define Q30 30 +#define Q29 29 +#define Q28 28 +#define Q27 27 +#define Q26 26 +#define Q25 25 +#define Q24 24 +#define Q23 23 +#define Q22 22 +#define Q21 21 +#define Q20 20 +#define Q19 19 +#define Q18 18 +#define Q17 17 +#define Q16 16 +#define Q15 15 +#define Q14 14 +#define Q13 13 +#define Q12 12 +#define Q11 11 +#define Q10 10 +#define Q9 9 +#define Q8 8 +#define Q7 7 +#define Q6 6 +#define Q5 5 +#define Q4 4 +#define Q3 3 +#define Q2 2 +#define Q1 1 +#define QG GLOBAL_Q + +#define MAX_IQ_POS LONG_MAX +#define MAX_IQ_NEG LONG_MIN +#define MIN_IQ_POS 1 +#define MIN_IQ_NEG -1 + +//***************************************************************************** +// +// See if IQmath or floating point is being used. +// +//***************************************************************************** +#if MATH_TYPE == IQ_MATH + +//***************************************************************************** +// +// The types for the various IQ formats. +// +//***************************************************************************** +typedef long _iq30; +typedef long _iq29; +typedef long _iq28; +typedef long _iq27; +typedef long _iq26; +typedef long _iq25; +typedef long _iq24; +typedef long _iq23; +typedef long _iq22; +typedef long _iq21; +typedef long _iq20; +typedef long _iq19; +typedef long _iq18; +typedef long _iq17; +typedef long _iq16; +typedef long _iq15; +typedef long _iq14; +typedef long _iq13; +typedef long _iq12; +typedef long _iq11; +typedef long _iq10; +typedef long _iq9; +typedef long _iq8; +typedef long _iq7; +typedef long _iq6; +typedef long _iq5; +typedef long _iq4; +typedef long _iq3; +typedef long _iq2; +typedef long _iq1; +typedef long _iq; + +//***************************************************************************** +// +// Simple multiplies or divides, which are accomplished with simple shifts. +// +//***************************************************************************** +#define _IQmpy2(A) ((A) << 1) +#define _IQmpy4(A) ((A) << 2) +#define _IQmpy8(A) ((A) << 3) +#define _IQmpy16(A) ((A) << 4) +#define _IQmpy32(A) ((A) << 5) +#define _IQmpy64(A) ((A) << 6) +#define _IQdiv2(A) ((A) >> 1) +#define _IQdiv4(A) ((A) >> 2) +#define _IQdiv8(A) ((A) >> 3) +#define _IQdiv16(A) ((A) >> 4) +#define _IQdiv32(A) ((A) >> 5) +#define _IQdiv64(A) ((A) >> 6) + +//***************************************************************************** +// +// Convert a value into an IQ number. +// +//***************************************************************************** +#define _IQ30(A) ((_iq30)((A) * (1 << 30))) +#define _IQ29(A) ((_iq29)((A) * (1 << 29))) +#define _IQ28(A) ((_iq28)((A) * (1 << 28))) +#define _IQ27(A) ((_iq27)((A) * (1 << 27))) +#define _IQ26(A) ((_iq26)((A) * (1 << 26))) +#define _IQ25(A) ((_iq25)((A) * (1 << 25))) +#define _IQ24(A) ((_iq24)((A) * (1 << 24))) +#define _IQ23(A) ((_iq23)((A) * (1 << 23))) +#define _IQ22(A) ((_iq22)((A) * (1 << 22))) +#define _IQ21(A) ((_iq21)((A) * (1 << 21))) +#define _IQ20(A) ((_iq20)((A) * (1 << 20))) +#define _IQ19(A) ((_iq19)((A) * (1 << 19))) +#define _IQ18(A) ((_iq18)((A) * (1 << 18))) +#define _IQ17(A) ((_iq17)((A) * (1 << 17))) +#define _IQ16(A) ((_iq16)((A) * (1 << 16))) +#define _IQ15(A) ((_iq15)((A) * (1 << 15))) +#define _IQ14(A) ((_iq14)((A) * (1 << 14))) +#define _IQ13(A) ((_iq13)((A) * (1 << 13))) +#define _IQ12(A) ((_iq12)((A) * (1 << 12))) +#define _IQ11(A) ((_iq11)((A) * (1 << 11))) +#define _IQ10(A) ((_iq10)((A) * (1 << 10))) +#define _IQ9(A) ((_iq9)((A) * (1 << 9))) +#define _IQ8(A) ((_iq8)((A) * (1 << 8))) +#define _IQ7(A) ((_iq7)((A) * (1 << 7))) +#define _IQ6(A) ((_iq6)((A) * (1 << 6))) +#define _IQ5(A) ((_iq5)((A) * (1 << 5))) +#define _IQ4(A) ((_iq4)((A) * (1 << 4))) +#define _IQ3(A) ((_iq3)((A) * (1 << 3))) +#define _IQ2(A) ((_iq2)((A) * (1 << 2))) +#define _IQ1(A) ((_iq1)((A) * (1 << 1))) + +#if GLOBAL_Q == 30 +#define _IQ(A) _IQ30(A) +#endif +#if GLOBAL_Q == 29 +#define _IQ(A) _IQ29(A) +#endif +#if GLOBAL_Q == 28 +#define _IQ(A) _IQ28(A) +#endif +#if GLOBAL_Q == 27 +#define _IQ(A) _IQ27(A) +#endif +#if GLOBAL_Q == 26 +#define _IQ(A) _IQ26(A) +#endif +#if GLOBAL_Q == 25 +#define _IQ(A) _IQ25(A) +#endif +#if GLOBAL_Q == 24 +#define _IQ(A) _IQ24(A) +#endif +#if GLOBAL_Q == 23 +#define _IQ(A) _IQ23(A) +#endif +#if GLOBAL_Q == 22 +#define _IQ(A) _IQ22(A) +#endif +#if GLOBAL_Q == 21 +#define _IQ(A) _IQ21(A) +#endif +#if GLOBAL_Q == 20 +#define _IQ(A) _IQ20(A) +#endif +#if GLOBAL_Q == 19 +#define _IQ(A) _IQ19(A) +#endif +#if GLOBAL_Q == 18 +#define _IQ(A) _IQ18(A) +#endif +#if GLOBAL_Q == 17 +#define _IQ(A) _IQ17(A) +#endif +#if GLOBAL_Q == 16 +#define _IQ(A) _IQ16(A) +#endif +#if GLOBAL_Q == 15 +#define _IQ(A) _IQ15(A) +#endif +#if GLOBAL_Q == 14 +#define _IQ(A) _IQ14(A) +#endif +#if GLOBAL_Q == 13 +#define _IQ(A) _IQ13(A) +#endif +#if GLOBAL_Q == 12 +#define _IQ(A) _IQ12(A) +#endif +#if GLOBAL_Q == 11 +#define _IQ(A) _IQ11(A) +#endif +#if GLOBAL_Q == 10 +#define _IQ(A) _IQ10(A) +#endif +#if GLOBAL_Q == 9 +#define _IQ(A) _IQ9(A) +#endif +#if GLOBAL_Q == 8 +#define _IQ(A) _IQ8(A) +#endif +#if GLOBAL_Q == 7 +#define _IQ(A) _IQ7(A) +#endif +#if GLOBAL_Q == 6 +#define _IQ(A) _IQ6(A) +#endif +#if GLOBAL_Q == 5 +#define _IQ(A) _IQ5(A) +#endif +#if GLOBAL_Q == 4 +#define _IQ(A) _IQ4(A) +#endif +#if GLOBAL_Q == 3 +#define _IQ(A) _IQ3(A) +#endif +#if GLOBAL_Q == 2 +#define _IQ(A) _IQ2(A) +#endif +#if GLOBAL_Q == 1 +#define _IQ(A) _IQ1(A) +#endif + +//***************************************************************************** +// +// Convert an IQ number to a floating point value. +// +//***************************************************************************** +extern float _IQ30toF(_iq30 A); +extern float _IQ29toF(_iq29 A); +extern float _IQ28toF(_iq28 A); +extern float _IQ27toF(_iq27 A); +extern float _IQ26toF(_iq26 A); +extern float _IQ25toF(_iq25 A); +extern float _IQ24toF(_iq24 A); +extern float _IQ23toF(_iq23 A); +extern float _IQ22toF(_iq22 A); +extern float _IQ21toF(_iq21 A); +extern float _IQ20toF(_iq20 A); +extern float _IQ19toF(_iq19 A); +extern float _IQ18toF(_iq18 A); +extern float _IQ17toF(_iq17 A); +extern float _IQ16toF(_iq16 A); +extern float _IQ15toF(_iq15 A); +extern float _IQ14toF(_iq14 A); +extern float _IQ13toF(_iq13 A); +extern float _IQ12toF(_iq12 A); +extern float _IQ11toF(_iq11 A); +extern float _IQ10toF(_iq10 A); +extern float _IQ9toF(_iq9 A); +extern float _IQ8toF(_iq8 A); +extern float _IQ7toF(_iq7 A); +extern float _IQ6toF(_iq6 A); +extern float _IQ5toF(_iq5 A); +extern float _IQ4toF(_iq4 A); +extern float _IQ3toF(_iq3 A); +extern float _IQ2toF(_iq2 A); +extern float _IQ1toF(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQtoF(A) _IQ30toF(A) +#endif +#if GLOBAL_Q == 29 +#define _IQtoF(A) _IQ29toF(A) +#endif +#if GLOBAL_Q == 28 +#define _IQtoF(A) _IQ28toF(A) +#endif +#if GLOBAL_Q == 27 +#define _IQtoF(A) _IQ27toF(A) +#endif +#if GLOBAL_Q == 26 +#define _IQtoF(A) _IQ26toF(A) +#endif +#if GLOBAL_Q == 25 +#define _IQtoF(A) _IQ25toF(A) +#endif +#if GLOBAL_Q == 24 +#define _IQtoF(A) _IQ24toF(A) +#endif +#if GLOBAL_Q == 23 +#define _IQtoF(A) _IQ23toF(A) +#endif +#if GLOBAL_Q == 22 +#define _IQtoF(A) _IQ22toF(A) +#endif +#if GLOBAL_Q == 21 +#define _IQtoF(A) _IQ21toF(A) +#endif +#if GLOBAL_Q == 20 +#define _IQtoF(A) _IQ20toF(A) +#endif +#if GLOBAL_Q == 19 +#define _IQtoF(A) _IQ19toF(A) +#endif +#if GLOBAL_Q == 18 +#define _IQtoF(A) _IQ18toF(A) +#endif +#if GLOBAL_Q == 17 +#define _IQtoF(A) _IQ17toF(A) +#endif +#if GLOBAL_Q == 16 +#define _IQtoF(A) _IQ16toF(A) +#endif +#if GLOBAL_Q == 15 +#define _IQtoF(A) _IQ15toF(A) +#endif +#if GLOBAL_Q == 14 +#define _IQtoF(A) _IQ14toF(A) +#endif +#if GLOBAL_Q == 13 +#define _IQtoF(A) _IQ13toF(A) +#endif +#if GLOBAL_Q == 12 +#define _IQtoF(A) _IQ12toF(A) +#endif +#if GLOBAL_Q == 11 +#define _IQtoF(A) _IQ11toF(A) +#endif +#if GLOBAL_Q == 10 +#define _IQtoF(A) _IQ10toF(A) +#endif +#if GLOBAL_Q == 9 +#define _IQtoF(A) _IQ9toF(A) +#endif +#if GLOBAL_Q == 8 +#define _IQtoF(A) _IQ8toF(A) +#endif +#if GLOBAL_Q == 7 +#define _IQtoF(A) _IQ7toF(A) +#endif +#if GLOBAL_Q == 6 +#define _IQtoF(A) _IQ6toF(A) +#endif +#if GLOBAL_Q == 5 +#define _IQtoF(A) _IQ5toF(A) +#endif +#if GLOBAL_Q == 4 +#define _IQtoF(A) _IQ4toF(A) +#endif +#if GLOBAL_Q == 3 +#define _IQtoF(A) _IQ3toF(A) +#endif +#if GLOBAL_Q == 2 +#define _IQtoF(A) _IQ2toF(A) +#endif +#if GLOBAL_Q == 1 +#define _IQtoF(A) _IQ1toF(A) +#endif + +//***************************************************************************** +// +// Convert an IQ number to a double-precision floating point value. +// +//***************************************************************************** +extern double _IQ30toD(_iq30 A); +extern double _IQ29toD(_iq29 A); +extern double _IQ28toD(_iq28 A); +extern double _IQ27toD(_iq27 A); +extern double _IQ26toD(_iq26 A); +extern double _IQ25toD(_iq25 A); +extern double _IQ24toD(_iq24 A); +extern double _IQ23toD(_iq23 A); +extern double _IQ22toD(_iq22 A); +extern double _IQ21toD(_iq21 A); +extern double _IQ20toD(_iq20 A); +extern double _IQ19toD(_iq19 A); +extern double _IQ18toD(_iq18 A); +extern double _IQ17toD(_iq17 A); +extern double _IQ16toD(_iq16 A); +extern double _IQ15toD(_iq15 A); +extern double _IQ14toD(_iq14 A); +extern double _IQ13toD(_iq13 A); +extern double _IQ12toD(_iq12 A); +extern double _IQ11toD(_iq11 A); +extern double _IQ10toD(_iq10 A); +extern double _IQ9toD(_iq9 A); +extern double _IQ8toD(_iq8 A); +extern double _IQ7toD(_iq7 A); +extern double _IQ6toD(_iq6 A); +extern double _IQ5toD(_iq5 A); +extern double _IQ4toD(_iq4 A); +extern double _IQ3toD(_iq3 A); +extern double _IQ2toD(_iq2 A); +extern double _IQ1toD(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQtoD(A) _IQ30toD(A) +#endif +#if GLOBAL_Q == 29 +#define _IQtoD(A) _IQ29toD(A) +#endif +#if GLOBAL_Q == 28 +#define _IQtoD(A) _IQ28toD(A) +#endif +#if GLOBAL_Q == 27 +#define _IQtoD(A) _IQ27toD(A) +#endif +#if GLOBAL_Q == 26 +#define _IQtoD(A) _IQ26toD(A) +#endif +#if GLOBAL_Q == 25 +#define _IQtoD(A) _IQ25toD(A) +#endif +#if GLOBAL_Q == 24 +#define _IQtoD(A) _IQ24toD(A) +#endif +#if GLOBAL_Q == 23 +#define _IQtoD(A) _IQ23toD(A) +#endif +#if GLOBAL_Q == 22 +#define _IQtoD(A) _IQ22toD(A) +#endif +#if GLOBAL_Q == 21 +#define _IQtoD(A) _IQ21toD(A) +#endif +#if GLOBAL_Q == 20 +#define _IQtoD(A) _IQ20toD(A) +#endif +#if GLOBAL_Q == 19 +#define _IQtoD(A) _IQ19toD(A) +#endif +#if GLOBAL_Q == 18 +#define _IQtoD(A) _IQ18toD(A) +#endif +#if GLOBAL_Q == 17 +#define _IQtoD(A) _IQ17toD(A) +#endif +#if GLOBAL_Q == 16 +#define _IQtoD(A) _IQ16toD(A) +#endif +#if GLOBAL_Q == 15 +#define _IQtoD(A) _IQ15toD(A) +#endif +#if GLOBAL_Q == 14 +#define _IQtoD(A) _IQ14toD(A) +#endif +#if GLOBAL_Q == 13 +#define _IQtoD(A) _IQ13toD(A) +#endif +#if GLOBAL_Q == 12 +#define _IQtoD(A) _IQ12toD(A) +#endif +#if GLOBAL_Q == 11 +#define _IQtoD(A) _IQ11toD(A) +#endif +#if GLOBAL_Q == 10 +#define _IQtoD(A) _IQ10toD(A) +#endif +#if GLOBAL_Q == 9 +#define _IQtoD(A) _IQ9toD(A) +#endif +#if GLOBAL_Q == 8 +#define _IQtoD(A) _IQ8toD(A) +#endif +#if GLOBAL_Q == 7 +#define _IQtoD(A) _IQ7toD(A) +#endif +#if GLOBAL_Q == 6 +#define _IQtoD(A) _IQ6toD(A) +#endif +#if GLOBAL_Q == 5 +#define _IQtoD(A) _IQ5toD(A) +#endif +#if GLOBAL_Q == 4 +#define _IQtoD(A) _IQ4toD(A) +#endif +#if GLOBAL_Q == 3 +#define _IQtoD(A) _IQ3toD(A) +#endif +#if GLOBAL_Q == 2 +#define _IQtoD(A) _IQ2toD(A) +#endif +#if GLOBAL_Q == 1 +#define _IQtoD(A) _IQ1toD(A) +#endif + +//***************************************************************************** +// +// Saturates an IQ number in a given range. +// +//***************************************************************************** +#define _IQsat(A, Pos, Neg) (((A) > (Pos)) ? \ + (Pos) : \ + (((A) < (Neg)) ? (Neg) : (A))) + +//***************************************************************************** +// +// Converts an IQ number between the global IQ format and a specified IQ +// format. +// +//***************************************************************************** +#define _IQtoIQ30(A) ((_iq30)(A) << (30 - GLOBAL_Q)) +#define _IQ30toIQ(A) ((_iq30)(A) >> (30 - GLOBAL_Q)) + +#if (GLOBAL_Q >= 29) +#define _IQtoIQ29(A) ((_iq29)(A) >> (GLOBAL_Q - 29)) +#define _IQ29toIQ(A) ((_iq29)(A) << (GLOBAL_Q - 29)) +#else +#define _IQtoIQ29(A) ((_iq29)(A) << (29 - GLOBAL_Q)) +#define _IQ29toIQ(A) ((_iq29)(A) >> (29 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 28) +#define _IQtoIQ28(A) ((_iq28)(A) >> (GLOBAL_Q - 28)) +#define _IQ28toIQ(A) ((_iq28)(A) << (GLOBAL_Q - 28)) +#else +#define _IQtoIQ28(A) ((_iq28)(A) << (28 - GLOBAL_Q)) +#define _IQ28toIQ(A) ((_iq28)(A) >> (28 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 27) +#define _IQtoIQ27(A) ((_iq27)(A) >> (GLOBAL_Q - 27)) +#define _IQ27toIQ(A) ((_iq27)(A) << (GLOBAL_Q - 27)) +#else +#define _IQtoIQ27(A) ((_iq27)(A) << (27 - GLOBAL_Q)) +#define _IQ27toIQ(A) ((_iq27)(A) >> (27 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 26) +#define _IQtoIQ26(A) ((_iq26)(A) >> (GLOBAL_Q - 26)) +#define _IQ26toIQ(A) ((_iq26)(A) << (GLOBAL_Q - 26)) +#else +#define _IQtoIQ26(A) ((_iq26)(A) << (26 - GLOBAL_Q)) +#define _IQ26toIQ(A) ((_iq26)(A) >> (26 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 25) +#define _IQtoIQ25(A) ((_iq25)(A) >> (GLOBAL_Q - 25)) +#define _IQ25toIQ(A) ((_iq25)(A) << (GLOBAL_Q - 25)) +#else +#define _IQtoIQ25(A) ((_iq25)(A) << (25 - GLOBAL_Q)) +#define _IQ25toIQ(A) ((_iq25)(A) >> (25 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 24) +#define _IQtoIQ24(A) ((_iq24)(A) >> (GLOBAL_Q - 24)) +#define _IQ24toIQ(A) ((_iq24)(A) << (GLOBAL_Q - 24)) +#else +#define _IQtoIQ24(A) ((_iq24)(A) << (24 - GLOBAL_Q)) +#define _IQ24toIQ(A) ((_iq24)(A) >> (24 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 23) +#define _IQtoIQ23(A) ((_iq23)(A) >> (GLOBAL_Q - 23)) +#define _IQ23toIQ(A) ((_iq23)(A) << (GLOBAL_Q - 23)) +#else +#define _IQtoIQ23(A) ((_iq23)(A) << (23 - GLOBAL_Q)) +#define _IQ23toIQ(A) ((_iq23)(A) >> (23 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 22) +#define _IQtoIQ22(A) ((_iq22)(A) >> (GLOBAL_Q - 22)) +#define _IQ22toIQ(A) ((_iq22)(A) << (GLOBAL_Q - 22)) +#else +#define _IQtoIQ22(A) ((_iq22)(A) << (22 - GLOBAL_Q)) +#define _IQ22toIQ(A) ((_iq22)(A) >> (22 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 21) +#define _IQtoIQ21(A) ((_iq21)(A) >> (GLOBAL_Q - 21)) +#define _IQ21toIQ(A) ((_iq21)(A) << (GLOBAL_Q - 21)) +#else +#define _IQtoIQ21(A) ((_iq21)(A) << (21 - GLOBAL_Q)) +#define _IQ21toIQ(A) ((_iq21)(A) >> (21 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 20) +#define _IQtoIQ20(A) ((_iq20)(A) >> (GLOBAL_Q - 20)) +#define _IQ20toIQ(A) ((_iq20)(A) << (GLOBAL_Q - 20)) +#else +#define _IQtoIQ20(A) ((_iq20)(A) << (20 - GLOBAL_Q)) +#define _IQ20toIQ(A) ((_iq20)(A) >> (20 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 19) +#define _IQtoIQ19(A) ((_iq19)(A) >> (GLOBAL_Q - 19)) +#define _IQ19toIQ(A) ((_iq19)(A) << (GLOBAL_Q - 19)) +#else +#define _IQtoIQ19(A) ((_iq19)(A) << (19 - GLOBAL_Q)) +#define _IQ19toIQ(A) ((_iq19)(A) >> (19 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 18) +#define _IQtoIQ18(A) ((_iq18)(A) >> (GLOBAL_Q - 18)) +#define _IQ18toIQ(A) ((_iq18)(A) << (GLOBAL_Q - 18)) +#else +#define _IQtoIQ18(A) ((_iq18)(A) << (18 - GLOBAL_Q)) +#define _IQ18toIQ(A) ((_iq18)(A) >> (18 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 17) +#define _IQtoIQ17(A) ((_iq17)(A) >> (GLOBAL_Q - 17)) +#define _IQ17toIQ(A) ((_iq17)(A) << (GLOBAL_Q - 17)) +#else +#define _IQtoIQ17(A) ((_iq17)(A) << (17 - GLOBAL_Q)) +#define _IQ17toIQ(A) ((_iq17)(A) >> (17 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 16) +#define _IQtoIQ16(A) ((_iq16)(A) >> (GLOBAL_Q - 16)) +#define _IQ16toIQ(A) ((_iq16)(A) << (GLOBAL_Q - 16)) +#else +#define _IQtoIQ16(A) ((_iq16)(A) << (16 - GLOBAL_Q)) +#define _IQ16toIQ(A) ((_iq16)(A) >> (16 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 15) +#define _IQtoIQ15(A) ((_iq15)(A) >> (GLOBAL_Q - 15)) +#define _IQ15toIQ(A) ((_iq15)(A) << (GLOBAL_Q - 15)) +#else +#define _IQtoIQ15(A) ((_iq15)(A) << (15 - GLOBAL_Q)) +#define _IQ15toIQ(A) ((_iq15)(A) >> (15 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 14) +#define _IQtoIQ14(A) ((_iq14)(A) >> (GLOBAL_Q - 14)) +#define _IQ14toIQ(A) ((_iq14)(A) << (GLOBAL_Q - 14)) +#else +#define _IQtoIQ14(A) ((_iq14)(A) << (14 - GLOBAL_Q)) +#define _IQ14toIQ(A) ((_iq14)(A) >> (14 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 13) +#define _IQtoIQ13(A) ((_iq13)(A) >> (GLOBAL_Q - 13)) +#define _IQ13toIQ(A) ((_iq13)(A) << (GLOBAL_Q - 13)) +#else +#define _IQtoIQ13(A) ((_iq13)(A) << (13 - GLOBAL_Q)) +#define _IQ13toIQ(A) ((_iq13)(A) >> (13 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 12) +#define _IQtoIQ12(A) ((_iq12)(A) >> (GLOBAL_Q - 12)) +#define _IQ12toIQ(A) ((_iq12)(A) << (GLOBAL_Q - 12)) +#else +#define _IQtoIQ12(A) ((_iq12)(A) << (12 - GLOBAL_Q)) +#define _IQ12toIQ(A) ((_iq12)(A) >> (12 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 11) +#define _IQtoIQ11(A) ((_iq11)(A) >> (GLOBAL_Q - 11)) +#define _IQ11toIQ(A) ((_iq11)(A) << (GLOBAL_Q - 11)) +#else +#define _IQtoIQ11(A) ((_iq11)(A) << (11 - GLOBAL_Q)) +#define _IQ11toIQ(A) ((_iq11)(A) >> (11 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 10) +#define _IQtoIQ10(A) ((_iq10)(A) >> (GLOBAL_Q - 10)) +#define _IQ10toIQ(A) ((_iq10)(A) << (GLOBAL_Q - 10)) +#else +#define _IQtoIQ10(A) ((_iq10)(A) << (10 - GLOBAL_Q)) +#define _IQ10toIQ(A) ((_iq10)(A) >> (10 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 9) +#define _IQtoIQ9(A) ((_iq9)(A) >> (GLOBAL_Q - 9)) +#define _IQ9toIQ(A) ((_iq9)(A) << (GLOBAL_Q - 9)) +#else +#define _IQtoIQ9(A) ((_iq9)(A) << (9 - GLOBAL_Q)) +#define _IQ9toIQ(A) ((_iq9)(A) >> (9 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 8) +#define _IQtoIQ8(A) ((_iq8)(A) >> (GLOBAL_Q - 8)) +#define _IQ8toIQ(A) ((_iq8)(A) << (GLOBAL_Q - 8)) +#else +#define _IQtoIQ8(A) ((_iq8)(A) << (8 - GLOBAL_Q)) +#define _IQ8toIQ(A) ((_iq8)(A) >> (8 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 7) +#define _IQtoIQ7(A) ((_iq7)(A) >> (GLOBAL_Q - 7)) +#define _IQ7toIQ(A) ((_iq7)(A) << (GLOBAL_Q - 7)) +#else +#define _IQtoIQ7(A) ((_iq7)(A) << (7 - GLOBAL_Q)) +#define _IQ7toIQ(A) ((_iq7)(A) >> (7 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 6) +#define _IQtoIQ6(A) ((_iq6)(A) >> (GLOBAL_Q - 6)) +#define _IQ6toIQ(A) ((_iq6)(A) << (GLOBAL_Q - 6)) +#else +#define _IQtoIQ6(A) ((_iq6)(A) << (6 - GLOBAL_Q)) +#define _IQ6toIQ(A) ((_iq6)(A) >> (6 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 5) +#define _IQtoIQ5(A) ((_iq5)(A) >> (GLOBAL_Q - 5)) +#define _IQ5toIQ(A) ((_iq5)(A) << (GLOBAL_Q - 5)) +#else +#define _IQtoIQ5(A) ((_iq5)(A) << (5 - GLOBAL_Q)) +#define _IQ5toIQ(A) ((_iq5)(A) >> (5 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 4) +#define _IQtoIQ4(A) ((_iq4)(A) >> (GLOBAL_Q - 4)) +#define _IQ4toIQ(A) ((_iq4)(A) << (GLOBAL_Q - 4)) +#else +#define _IQtoIQ4(A) ((_iq4)(A) << (4 - GLOBAL_Q)) +#define _IQ4toIQ(A) ((_iq4)(A) >> (4 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 3) +#define _IQtoIQ3(A) ((_iq3)(A) >> (GLOBAL_Q - 3)) +#define _IQ3toIQ(A) ((_iq3)(A) << (GLOBAL_Q - 3)) +#else +#define _IQtoIQ3(A) ((_iq3)(A) << (3 - GLOBAL_Q)) +#define _IQ3toIQ(A) ((_iq3)(A) >> (3 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 2) +#define _IQtoIQ2(A) ((_iq2)(A) >> (GLOBAL_Q - 2)) +#define _IQ2toIQ(A) ((_iq2)(A) << (GLOBAL_Q - 2)) +#else +#define _IQtoIQ2(A) ((_iq2)(A) << (2 - GLOBAL_Q)) +#define _IQ2toIQ(A) ((_iq2)(A) >> (2 - GLOBAL_Q)) +#endif + +#define _IQtoIQ1(A) ((_iq1)(A) >> (GLOBAL_Q - 1)) +#define _IQ1toIQ(A) ((_iq1)(A) << (GLOBAL_Q - 1)) + +//***************************************************************************** +// +// Converts a number between IQ format and 16-bit Qn format. +// +//***************************************************************************** +#if (GLOBAL_Q >= 15) +#define _IQtoQ15(A) ((long)(A) >> (GLOBAL_Q - 15)) +#define _Q15toIQ(A) ((_iq15)(A) << (GLOBAL_Q - 15)) +#else +#define _IQtoQ15(A) ((long)(A) << (15 - GLOBAL_Q)) +#define _Q15toIQ(A) ((_iq15)(A) >> (15 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 14) +#define _IQtoQ14(A) ((long)(A) >> (GLOBAL_Q - 14)) +#define _Q14toIQ(A) ((_iq14)(A) << (GLOBAL_Q - 14)) +#else +#define _IQtoQ14(A) ((long)(A) << (14 - GLOBAL_Q)) +#define _Q14toIQ(A) ((_iq14)(A) >> (14 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 13) +#define _IQtoQ13(A) ((long)(A) >> (GLOBAL_Q - 13)) +#define _Q13toIQ(A) ((_iq13)(A) << (GLOBAL_Q - 13)) +#else +#define _IQtoQ13(A) ((long)(A) << (13 - GLOBAL_Q)) +#define _Q13toIQ(A) ((_iq13)(A) >> (13 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 12) +#define _IQtoQ12(A) ((long)(A) >> (GLOBAL_Q - 12)) +#define _Q12toIQ(A) ((_iq12)(A) << (GLOBAL_Q - 12)) +#else +#define _IQtoQ12(A) ((long)(A) << (12 - GLOBAL_Q)) +#define _Q12toIQ(A) ((_iq12)(A) >> (12 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 11) +#define _IQtoQ11(A) ((long)(A) >> (GLOBAL_Q - 11)) +#define _Q11toIQ(A) ((_iq11)(A) << (GLOBAL_Q - 11)) +#else +#define _IQtoQ11(A) ((long)(A) << (11 - GLOBAL_Q)) +#define _Q11toIQ(A) ((_iq11)(A) >> (11 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 10) +#define _IQtoQ10(A) ((long)(A) >> (GLOBAL_Q - 10)) +#define _Q10toIQ(A) ((_iq10)(A) << (GLOBAL_Q - 10)) +#else +#define _IQtoQ10(A) ((long)(A) << (10 - GLOBAL_Q)) +#define _Q10toIQ(A) ((_iq10)(A) >> (10 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 9) +#define _IQtoQ9(A) ((long)(A) >> (GLOBAL_Q - 9)) +#define _Q9toIQ(A) ((_iq9)(A) << (GLOBAL_Q - 9)) +#else +#define _IQtoQ9(A) ((long)(A) << (9 - GLOBAL_Q)) +#define _Q9toIQ(A) ((_iq9)(A) >> (9 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 8) +#define _IQtoQ8(A) ((long)(A) >> (GLOBAL_Q - 8)) +#define _Q8toIQ(A) ((_iq8)(A) << (GLOBAL_Q - 8)) +#else +#define _IQtoQ8(A) ((long)(A) << (8 - GLOBAL_Q)) +#define _Q8toIQ(A) ((_iq8)(A) >> (8 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 7) +#define _IQtoQ7(A) ((long)(A) >> (GLOBAL_Q - 7)) +#define _Q7toIQ(A) ((_iq7)(A) << (GLOBAL_Q - 7)) +#else +#define _IQtoQ7(A) ((long)(A) << (7 - GLOBAL_Q)) +#define _Q7toIQ(A) ((_iq7)(A) >> (7 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 6) +#define _IQtoQ6(A) ((long)(A) >> (GLOBAL_Q - 6)) +#define _Q6toIQ(A) ((_iq6)(A) << (GLOBAL_Q - 6)) +#else +#define _IQtoQ6(A) ((long)(A) << (6 - GLOBAL_Q)) +#define _Q6toIQ(A) ((_iq6)(A) >> (6 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 5) +#define _IQtoQ5(A) ((long)(A) >> (GLOBAL_Q - 5)) +#define _Q5toIQ(A) ((_iq5)(A) << (GLOBAL_Q - 5)) +#else +#define _IQtoQ5(A) ((long)(A) << (5 - GLOBAL_Q)) +#define _Q5toIQ(A) ((_iq5)(A) >> (5 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 4) +#define _IQtoQ4(A) ((long)(A) >> (GLOBAL_Q - 4)) +#define _Q4toIQ(A) ((_iq4)(A) << (GLOBAL_Q - 4)) +#else +#define _IQtoQ4(A) ((long)(A) << (4 - GLOBAL_Q)) +#define _Q4toIQ(A) ((_iq4)(A) >> (4 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 3) +#define _IQtoQ3(A) ((long)(A) >> (GLOBAL_Q - 3)) +#define _Q3toIQ(A) ((_iq3)(A) << (GLOBAL_Q - 3)) +#else +#define _IQtoQ3(A) ((long)(A) << (3 - GLOBAL_Q)) +#define _Q3toIQ(A) ((_iq3)(A) >> (3 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 2) +#define _IQtoQ2(A) ((long)(A) >> (GLOBAL_Q - 2)) +#define _Q2toIQ(A) ((_iq2)(A) << (GLOBAL_Q - 2)) +#else +#define _IQtoQ2(A) ((long)(A) << (2 - GLOBAL_Q)) +#define _Q2toIQ(A) ((_iq2)(A) >> (2 - GLOBAL_Q)) +#endif + +#define _IQtoQ1(A) ((long)(A) >> (GLOBAL_Q - 1)) +#define _Q1toIQ(A) ((_iq1)(A) << (GLOBAL_Q - 1)) + +//***************************************************************************** +// +// Multiplies two IQ numbers. +// +//***************************************************************************** +extern _iq30 _IQ30mpy(_iq30 A, _iq30 B); +extern _iq29 _IQ29mpy(_iq29 A, _iq29 B); +extern _iq28 _IQ28mpy(_iq28 A, _iq28 B); +extern _iq27 _IQ27mpy(_iq27 A, _iq27 B); +extern _iq26 _IQ26mpy(_iq26 A, _iq26 B); +extern _iq25 _IQ25mpy(_iq25 A, _iq25 B); +extern _iq24 _IQ24mpy(_iq24 A, _iq24 B); +extern _iq23 _IQ23mpy(_iq23 A, _iq23 B); +extern _iq22 _IQ22mpy(_iq22 A, _iq22 B); +extern _iq21 _IQ21mpy(_iq21 A, _iq21 B); +extern _iq20 _IQ20mpy(_iq20 A, _iq20 B); +extern _iq19 _IQ19mpy(_iq19 A, _iq19 B); +extern _iq18 _IQ18mpy(_iq18 A, _iq18 B); +extern _iq17 _IQ17mpy(_iq17 A, _iq17 B); +extern _iq16 _IQ16mpy(_iq16 A, _iq16 B); +extern _iq15 _IQ15mpy(_iq15 A, _iq15 B); +extern _iq14 _IQ14mpy(_iq14 A, _iq14 B); +extern _iq13 _IQ13mpy(_iq13 A, _iq13 B); +extern _iq12 _IQ12mpy(_iq12 A, _iq12 B); +extern _iq11 _IQ11mpy(_iq11 A, _iq11 B); +extern _iq10 _IQ10mpy(_iq10 A, _iq10 B); +extern _iq9 _IQ9mpy(_iq9 A, _iq9 B); +extern _iq8 _IQ8mpy(_iq8 A, _iq8 B); +extern _iq7 _IQ7mpy(_iq7 A, _iq7 B); +extern _iq6 _IQ6mpy(_iq6 A, _iq6 B); +extern _iq5 _IQ5mpy(_iq5 A, _iq5 B); +extern _iq4 _IQ4mpy(_iq4 A, _iq4 B); +extern _iq3 _IQ3mpy(_iq3 A, _iq3 B); +extern _iq2 _IQ2mpy(_iq2 A, _iq2 B); +extern _iq1 _IQ1mpy(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQmpy(A, B) _IQ30mpy(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQmpy(A, B) _IQ29mpy(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQmpy(A, B) _IQ28mpy(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQmpy(A, B) _IQ27mpy(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQmpy(A, B) _IQ26mpy(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQmpy(A, B) _IQ25mpy(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQmpy(A, B) _IQ24mpy(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQmpy(A, B) _IQ23mpy(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQmpy(A, B) _IQ22mpy(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQmpy(A, B) _IQ21mpy(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQmpy(A, B) _IQ20mpy(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQmpy(A, B) _IQ19mpy(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQmpy(A, B) _IQ18mpy(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQmpy(A, B) _IQ17mpy(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQmpy(A, B) _IQ16mpy(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQmpy(A, B) _IQ15mpy(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQmpy(A, B) _IQ14mpy(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQmpy(A, B) _IQ13mpy(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQmpy(A, B) _IQ12mpy(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQmpy(A, B) _IQ11mpy(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQmpy(A, B) _IQ10mpy(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQmpy(A, B) _IQ9mpy(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQmpy(A, B) _IQ8mpy(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQmpy(A, B) _IQ7mpy(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQmpy(A, B) _IQ6mpy(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQmpy(A, B) _IQ5mpy(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQmpy(A, B) _IQ4mpy(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQmpy(A, B) _IQ3mpy(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQmpy(A, B) _IQ2mpy(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQmpy(A, B) _IQ1mpy(A, B) +#endif + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding. +// +//***************************************************************************** +extern _iq30 _IQ30rmpy(_iq30 A, _iq30 B); +extern _iq29 _IQ29rmpy(_iq29 A, _iq29 B); +extern _iq28 _IQ28rmpy(_iq28 A, _iq28 B); +extern _iq27 _IQ27rmpy(_iq27 A, _iq27 B); +extern _iq26 _IQ26rmpy(_iq26 A, _iq26 B); +extern _iq25 _IQ25rmpy(_iq25 A, _iq25 B); +extern _iq24 _IQ24rmpy(_iq24 A, _iq24 B); +extern _iq23 _IQ23rmpy(_iq23 A, _iq23 B); +extern _iq22 _IQ22rmpy(_iq22 A, _iq22 B); +extern _iq21 _IQ21rmpy(_iq21 A, _iq21 B); +extern _iq20 _IQ20rmpy(_iq20 A, _iq20 B); +extern _iq19 _IQ19rmpy(_iq19 A, _iq19 B); +extern _iq18 _IQ18rmpy(_iq18 A, _iq18 B); +extern _iq17 _IQ17rmpy(_iq17 A, _iq17 B); +extern _iq16 _IQ16rmpy(_iq16 A, _iq16 B); +extern _iq15 _IQ15rmpy(_iq15 A, _iq15 B); +extern _iq14 _IQ14rmpy(_iq14 A, _iq14 B); +extern _iq13 _IQ13rmpy(_iq13 A, _iq13 B); +extern _iq12 _IQ12rmpy(_iq12 A, _iq12 B); +extern _iq11 _IQ11rmpy(_iq11 A, _iq11 B); +extern _iq10 _IQ10rmpy(_iq10 A, _iq10 B); +extern _iq9 _IQ9rmpy(_iq9 A, _iq9 B); +extern _iq8 _IQ8rmpy(_iq8 A, _iq8 B); +extern _iq7 _IQ7rmpy(_iq7 A, _iq7 B); +extern _iq6 _IQ6rmpy(_iq6 A, _iq6 B); +extern _iq5 _IQ5rmpy(_iq5 A, _iq5 B); +extern _iq4 _IQ4rmpy(_iq4 A, _iq4 B); +extern _iq3 _IQ3rmpy(_iq3 A, _iq3 B); +extern _iq2 _IQ2rmpy(_iq2 A, _iq2 B); +extern _iq1 _IQ1rmpy(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQrmpy(A, B) _IQ30rmpy(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQrmpy(A, B) _IQ29rmpy(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQrmpy(A, B) _IQ28rmpy(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQrmpy(A, B) _IQ27rmpy(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQrmpy(A, B) _IQ26rmpy(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQrmpy(A, B) _IQ25rmpy(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQrmpy(A, B) _IQ24rmpy(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQrmpy(A, B) _IQ23rmpy(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQrmpy(A, B) _IQ22rmpy(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQrmpy(A, B) _IQ21rmpy(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQrmpy(A, B) _IQ20rmpy(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQrmpy(A, B) _IQ19rmpy(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQrmpy(A, B) _IQ18rmpy(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQrmpy(A, B) _IQ17rmpy(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQrmpy(A, B) _IQ16rmpy(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQrmpy(A, B) _IQ15rmpy(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQrmpy(A, B) _IQ14rmpy(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQrmpy(A, B) _IQ13rmpy(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQrmpy(A, B) _IQ12rmpy(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQrmpy(A, B) _IQ11rmpy(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQrmpy(A, B) _IQ10rmpy(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQrmpy(A, B) _IQ9rmpy(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQrmpy(A, B) _IQ8rmpy(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQrmpy(A, B) _IQ7rmpy(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQrmpy(A, B) _IQ6rmpy(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQrmpy(A, B) _IQ5rmpy(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQrmpy(A, B) _IQ4rmpy(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQrmpy(A, B) _IQ3rmpy(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQrmpy(A, B) _IQ2rmpy(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQrmpy(A, B) _IQ1rmpy(A, B) +#endif + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding and saturation. +// +//***************************************************************************** +extern _iq30 _IQ30rsmpy(_iq30 A, _iq30 B); +extern _iq29 _IQ29rsmpy(_iq29 A, _iq29 B); +extern _iq28 _IQ28rsmpy(_iq28 A, _iq28 B); +extern _iq27 _IQ27rsmpy(_iq27 A, _iq27 B); +extern _iq26 _IQ26rsmpy(_iq26 A, _iq26 B); +extern _iq25 _IQ25rsmpy(_iq25 A, _iq25 B); +extern _iq24 _IQ24rsmpy(_iq24 A, _iq24 B); +extern _iq23 _IQ23rsmpy(_iq23 A, _iq23 B); +extern _iq22 _IQ22rsmpy(_iq22 A, _iq22 B); +extern _iq21 _IQ21rsmpy(_iq21 A, _iq21 B); +extern _iq20 _IQ20rsmpy(_iq20 A, _iq20 B); +extern _iq19 _IQ19rsmpy(_iq19 A, _iq19 B); +extern _iq18 _IQ18rsmpy(_iq18 A, _iq18 B); +extern _iq17 _IQ17rsmpy(_iq17 A, _iq17 B); +extern _iq16 _IQ16rsmpy(_iq16 A, _iq16 B); +extern _iq15 _IQ15rsmpy(_iq15 A, _iq15 B); +extern _iq14 _IQ14rsmpy(_iq14 A, _iq14 B); +extern _iq13 _IQ13rsmpy(_iq13 A, _iq13 B); +extern _iq12 _IQ12rsmpy(_iq12 A, _iq12 B); +extern _iq11 _IQ11rsmpy(_iq11 A, _iq11 B); +extern _iq10 _IQ10rsmpy(_iq10 A, _iq10 B); +extern _iq9 _IQ9rsmpy(_iq9 A, _iq9 B); +extern _iq8 _IQ8rsmpy(_iq8 A, _iq8 B); +extern _iq7 _IQ7rsmpy(_iq7 A, _iq7 B); +extern _iq6 _IQ6rsmpy(_iq6 A, _iq6 B); +extern _iq5 _IQ5rsmpy(_iq5 A, _iq5 B); +extern _iq4 _IQ4rsmpy(_iq4 A, _iq4 B); +extern _iq3 _IQ3rsmpy(_iq3 A, _iq3 B); +extern _iq2 _IQ2rsmpy(_iq2 A, _iq2 B); +extern _iq1 _IQ1rsmpy(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQrsmpy(A, B) _IQ30rsmpy(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQrsmpy(A, B) _IQ29rsmpy(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQrsmpy(A, B) _IQ28rsmpy(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQrsmpy(A, B) _IQ27rsmpy(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQrsmpy(A, B) _IQ26rsmpy(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQrsmpy(A, B) _IQ25rsmpy(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQrsmpy(A, B) _IQ24rsmpy(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQrsmpy(A, B) _IQ23rsmpy(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQrsmpy(A, B) _IQ22rsmpy(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQrsmpy(A, B) _IQ21rsmpy(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQrsmpy(A, B) _IQ20rsmpy(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQrsmpy(A, B) _IQ19rsmpy(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQrsmpy(A, B) _IQ18rsmpy(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQrsmpy(A, B) _IQ17rsmpy(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQrsmpy(A, B) _IQ16rsmpy(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQrsmpy(A, B) _IQ15rsmpy(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQrsmpy(A, B) _IQ14rsmpy(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQrsmpy(A, B) _IQ13rsmpy(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQrsmpy(A, B) _IQ12rsmpy(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQrsmpy(A, B) _IQ11rsmpy(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQrsmpy(A, B) _IQ10rsmpy(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQrsmpy(A, B) _IQ9rsmpy(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQrsmpy(A, B) _IQ8rsmpy(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQrsmpy(A, B) _IQ7rsmpy(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQrsmpy(A, B) _IQ6rsmpy(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQrsmpy(A, B) _IQ5rsmpy(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQrsmpy(A, B) _IQ4rsmpy(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQrsmpy(A, B) _IQ3rsmpy(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQrsmpy(A, B) _IQ2rsmpy(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQrsmpy(A, B) _IQ1rsmpy(A, B) +#endif + +//***************************************************************************** +// +// Divides two IQ numbers. +// +//***************************************************************************** +extern _iq30 _IQ30div(_iq30 A, _iq30 B); +extern _iq29 _IQ29div(_iq29 A, _iq29 B); +extern _iq28 _IQ28div(_iq28 A, _iq28 B); +extern _iq27 _IQ27div(_iq27 A, _iq27 B); +extern _iq26 _IQ26div(_iq26 A, _iq26 B); +extern _iq25 _IQ25div(_iq25 A, _iq25 B); +extern _iq24 _IQ24div(_iq24 A, _iq24 B); +extern _iq23 _IQ23div(_iq23 A, _iq23 B); +extern _iq22 _IQ22div(_iq22 A, _iq22 B); +extern _iq21 _IQ21div(_iq21 A, _iq21 B); +extern _iq20 _IQ20div(_iq20 A, _iq20 B); +extern _iq19 _IQ19div(_iq19 A, _iq19 B); +extern _iq18 _IQ18div(_iq18 A, _iq18 B); +extern _iq17 _IQ17div(_iq17 A, _iq17 B); +extern _iq16 _IQ16div(_iq16 A, _iq16 B); +extern _iq15 _IQ15div(_iq15 A, _iq15 B); +extern _iq14 _IQ14div(_iq14 A, _iq14 B); +extern _iq13 _IQ13div(_iq13 A, _iq13 B); +extern _iq12 _IQ12div(_iq12 A, _iq12 B); +extern _iq11 _IQ11div(_iq11 A, _iq11 B); +extern _iq10 _IQ10div(_iq10 A, _iq10 B); +extern _iq9 _IQ9div(_iq9 A, _iq9 B); +extern _iq8 _IQ8div(_iq8 A, _iq8 B); +extern _iq7 _IQ7div(_iq7 A, _iq7 B); +extern _iq6 _IQ6div(_iq6 A, _iq6 B); +extern _iq5 _IQ5div(_iq5 A, _iq5 B); +extern _iq4 _IQ4div(_iq4 A, _iq4 B); +extern _iq3 _IQ3div(_iq3 A, _iq3 B); +extern _iq2 _IQ2div(_iq2 A, _iq2 B); +extern _iq1 _IQ1div(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQdiv(A, B) _IQ30div(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQdiv(A, B) _IQ29div(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQdiv(A, B) _IQ28div(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQdiv(A, B) _IQ27div(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQdiv(A, B) _IQ26div(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQdiv(A, B) _IQ25div(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQdiv(A, B) _IQ24div(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQdiv(A, B) _IQ23div(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQdiv(A, B) _IQ22div(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQdiv(A, B) _IQ21div(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQdiv(A, B) _IQ20div(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQdiv(A, B) _IQ19div(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQdiv(A, B) _IQ18div(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQdiv(A, B) _IQ17div(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQdiv(A, B) _IQ16div(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQdiv(A, B) _IQ15div(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQdiv(A, B) _IQ14div(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQdiv(A, B) _IQ13div(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQdiv(A, B) _IQ12div(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQdiv(A, B) _IQ11div(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQdiv(A, B) _IQ10div(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQdiv(A, B) _IQ9div(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQdiv(A, B) _IQ8div(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQdiv(A, B) _IQ7div(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQdiv(A, B) _IQ6div(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQdiv(A, B) _IQ5div(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQdiv(A, B) _IQ4div(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQdiv(A, B) _IQ3div(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQdiv(A, B) _IQ2div(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQdiv(A, B) _IQ1div(A, B) +#endif + +//***************************************************************************** +// +// Computes the sin of an IQ number. +// +//***************************************************************************** +extern _iq29 _IQ29sin(_iq29 A); +extern _iq28 _IQ28sin(_iq28 A); +extern _iq27 _IQ27sin(_iq27 A); +extern _iq26 _IQ26sin(_iq26 A); +extern _iq25 _IQ25sin(_iq25 A); +extern _iq24 _IQ24sin(_iq24 A); +extern _iq23 _IQ23sin(_iq23 A); +extern _iq22 _IQ22sin(_iq22 A); +extern _iq21 _IQ21sin(_iq21 A); +extern _iq20 _IQ20sin(_iq20 A); +extern _iq19 _IQ19sin(_iq19 A); +extern _iq18 _IQ18sin(_iq18 A); +extern _iq17 _IQ17sin(_iq17 A); +extern _iq16 _IQ16sin(_iq16 A); +extern _iq15 _IQ15sin(_iq15 A); +extern _iq14 _IQ14sin(_iq14 A); +extern _iq13 _IQ13sin(_iq13 A); +extern _iq12 _IQ12sin(_iq12 A); +extern _iq11 _IQ11sin(_iq11 A); +extern _iq10 _IQ10sin(_iq10 A); +extern _iq9 _IQ9sin(_iq9 A); +extern _iq8 _IQ8sin(_iq8 A); +extern _iq7 _IQ7sin(_iq7 A); +extern _iq6 _IQ6sin(_iq6 A); +extern _iq5 _IQ5sin(_iq5 A); +extern _iq4 _IQ4sin(_iq4 A); +extern _iq3 _IQ3sin(_iq3 A); +extern _iq2 _IQ2sin(_iq2 A); +extern _iq1 _IQ1sin(_iq1 A); + +#if GLOBAL_Q == 29 +#define _IQsin(A) _IQ29sin(A) +#endif +#if GLOBAL_Q == 28 +#define _IQsin(A) _IQ28sin(A) +#endif +#if GLOBAL_Q == 27 +#define _IQsin(A) _IQ27sin(A) +#endif +#if GLOBAL_Q == 26 +#define _IQsin(A) _IQ26sin(A) +#endif +#if GLOBAL_Q == 25 +#define _IQsin(A) _IQ25sin(A) +#endif +#if GLOBAL_Q == 24 +#define _IQsin(A) _IQ24sin(A) +#endif +#if GLOBAL_Q == 23 +#define _IQsin(A) _IQ23sin(A) +#endif +#if GLOBAL_Q == 22 +#define _IQsin(A) _IQ22sin(A) +#endif +#if GLOBAL_Q == 21 +#define _IQsin(A) _IQ21sin(A) +#endif +#if GLOBAL_Q == 20 +#define _IQsin(A) _IQ20sin(A) +#endif +#if GLOBAL_Q == 19 +#define _IQsin(A) _IQ19sin(A) +#endif +#if GLOBAL_Q == 18 +#define _IQsin(A) _IQ18sin(A) +#endif +#if GLOBAL_Q == 17 +#define _IQsin(A) _IQ17sin(A) +#endif +#if GLOBAL_Q == 16 +#define _IQsin(A) _IQ16sin(A) +#endif +#if GLOBAL_Q == 15 +#define _IQsin(A) _IQ15sin(A) +#endif +#if GLOBAL_Q == 14 +#define _IQsin(A) _IQ14sin(A) +#endif +#if GLOBAL_Q == 13 +#define _IQsin(A) _IQ13sin(A) +#endif +#if GLOBAL_Q == 12 +#define _IQsin(A) _IQ12sin(A) +#endif +#if GLOBAL_Q == 11 +#define _IQsin(A) _IQ11sin(A) +#endif +#if GLOBAL_Q == 10 +#define _IQsin(A) _IQ10sin(A) +#endif +#if GLOBAL_Q == 9 +#define _IQsin(A) _IQ9sin(A) +#endif +#if GLOBAL_Q == 8 +#define _IQsin(A) _IQ8sin(A) +#endif +#if GLOBAL_Q == 7 +#define _IQsin(A) _IQ7sin(A) +#endif +#if GLOBAL_Q == 6 +#define _IQsin(A) _IQ6sin(A) +#endif +#if GLOBAL_Q == 5 +#define _IQsin(A) _IQ5sin(A) +#endif +#if GLOBAL_Q == 4 +#define _IQsin(A) _IQ4sin(A) +#endif +#if GLOBAL_Q == 3 +#define _IQsin(A) _IQ3sin(A) +#endif +#if GLOBAL_Q == 2 +#define _IQsin(A) _IQ2sin(A) +#endif +#if GLOBAL_Q == 1 +#define _IQsin(A) _IQ1sin(A) +#endif + +//***************************************************************************** +// +// Computes the sin of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +extern _iq30 _IQ30sinPU(_iq30 A); +extern _iq29 _IQ29sinPU(_iq29 A); +extern _iq28 _IQ28sinPU(_iq28 A); +extern _iq27 _IQ27sinPU(_iq27 A); +extern _iq26 _IQ26sinPU(_iq26 A); +extern _iq25 _IQ25sinPU(_iq25 A); +extern _iq24 _IQ24sinPU(_iq24 A); +extern _iq23 _IQ23sinPU(_iq23 A); +extern _iq22 _IQ22sinPU(_iq22 A); +extern _iq21 _IQ21sinPU(_iq21 A); +extern _iq20 _IQ20sinPU(_iq20 A); +extern _iq19 _IQ19sinPU(_iq19 A); +extern _iq18 _IQ18sinPU(_iq18 A); +extern _iq17 _IQ17sinPU(_iq17 A); +extern _iq16 _IQ16sinPU(_iq16 A); +extern _iq15 _IQ15sinPU(_iq15 A); +extern _iq14 _IQ14sinPU(_iq14 A); +extern _iq13 _IQ13sinPU(_iq13 A); +extern _iq12 _IQ12sinPU(_iq12 A); +extern _iq11 _IQ11sinPU(_iq11 A); +extern _iq10 _IQ10sinPU(_iq10 A); +extern _iq9 _IQ9sinPU(_iq9 A); +extern _iq8 _IQ8sinPU(_iq8 A); +extern _iq7 _IQ7sinPU(_iq7 A); +extern _iq6 _IQ6sinPU(_iq6 A); +extern _iq5 _IQ5sinPU(_iq5 A); +extern _iq4 _IQ4sinPU(_iq4 A); +extern _iq3 _IQ3sinPU(_iq3 A); +extern _iq2 _IQ2sinPU(_iq2 A); +extern _iq1 _IQ1sinPU(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQsinPU(A) _IQ30sinPU(A) +#endif +#if GLOBAL_Q == 29 +#define _IQsinPU(A) _IQ29sinPU(A) +#endif +#if GLOBAL_Q == 28 +#define _IQsinPU(A) _IQ28sinPU(A) +#endif +#if GLOBAL_Q == 27 +#define _IQsinPU(A) _IQ27sinPU(A) +#endif +#if GLOBAL_Q == 26 +#define _IQsinPU(A) _IQ26sinPU(A) +#endif +#if GLOBAL_Q == 25 +#define _IQsinPU(A) _IQ25sinPU(A) +#endif +#if GLOBAL_Q == 24 +#define _IQsinPU(A) _IQ24sinPU(A) +#endif +#if GLOBAL_Q == 23 +#define _IQsinPU(A) _IQ23sinPU(A) +#endif +#if GLOBAL_Q == 22 +#define _IQsinPU(A) _IQ22sinPU(A) +#endif +#if GLOBAL_Q == 21 +#define _IQsinPU(A) _IQ21sinPU(A) +#endif +#if GLOBAL_Q == 20 +#define _IQsinPU(A) _IQ20sinPU(A) +#endif +#if GLOBAL_Q == 19 +#define _IQsinPU(A) _IQ19sinPU(A) +#endif +#if GLOBAL_Q == 18 +#define _IQsinPU(A) _IQ18sinPU(A) +#endif +#if GLOBAL_Q == 17 +#define _IQsinPU(A) _IQ17sinPU(A) +#endif +#if GLOBAL_Q == 16 +#define _IQsinPU(A) _IQ16sinPU(A) +#endif +#if GLOBAL_Q == 15 +#define _IQsinPU(A) _IQ15sinPU(A) +#endif +#if GLOBAL_Q == 14 +#define _IQsinPU(A) _IQ14sinPU(A) +#endif +#if GLOBAL_Q == 13 +#define _IQsinPU(A) _IQ13sinPU(A) +#endif +#if GLOBAL_Q == 12 +#define _IQsinPU(A) _IQ12sinPU(A) +#endif +#if GLOBAL_Q == 11 +#define _IQsinPU(A) _IQ11sinPU(A) +#endif +#if GLOBAL_Q == 10 +#define _IQsinPU(A) _IQ10sinPU(A) +#endif +#if GLOBAL_Q == 9 +#define _IQsinPU(A) _IQ9sinPU(A) +#endif +#if GLOBAL_Q == 8 +#define _IQsinPU(A) _IQ8sinPU(A) +#endif +#if GLOBAL_Q == 7 +#define _IQsinPU(A) _IQ7sinPU(A) +#endif +#if GLOBAL_Q == 6 +#define _IQsinPU(A) _IQ6sinPU(A) +#endif +#if GLOBAL_Q == 5 +#define _IQsinPU(A) _IQ5sinPU(A) +#endif +#if GLOBAL_Q == 4 +#define _IQsinPU(A) _IQ4sinPU(A) +#endif +#if GLOBAL_Q == 3 +#define _IQsinPU(A) _IQ3sinPU(A) +#endif +#if GLOBAL_Q == 2 +#define _IQsinPU(A) _IQ2sinPU(A) +#endif +#if GLOBAL_Q == 1 +#define _IQsinPU(A) _IQ1sinPU(A) +#endif + +//***************************************************************************** +// +// Computes the arcsin of an IQ number. +// +//***************************************************************************** +extern _iq29 _IQ29asin(_iq29 A); +extern _iq28 _IQ28asin(_iq28 A); +extern _iq27 _IQ27asin(_iq27 A); +extern _iq26 _IQ26asin(_iq26 A); +extern _iq25 _IQ25asin(_iq25 A); +extern _iq24 _IQ24asin(_iq24 A); +extern _iq23 _IQ23asin(_iq23 A); +extern _iq22 _IQ22asin(_iq22 A); +extern _iq21 _IQ21asin(_iq21 A); +extern _iq20 _IQ20asin(_iq20 A); +extern _iq19 _IQ19asin(_iq19 A); +extern _iq18 _IQ18asin(_iq18 A); +extern _iq17 _IQ17asin(_iq17 A); +extern _iq16 _IQ16asin(_iq16 A); +extern _iq15 _IQ15asin(_iq15 A); +extern _iq14 _IQ14asin(_iq14 A); +extern _iq13 _IQ13asin(_iq13 A); +extern _iq12 _IQ12asin(_iq12 A); +extern _iq11 _IQ11asin(_iq11 A); +extern _iq10 _IQ10asin(_iq10 A); +extern _iq9 _IQ9asin(_iq9 A); +extern _iq8 _IQ8asin(_iq8 A); +extern _iq7 _IQ7asin(_iq7 A); +extern _iq6 _IQ6asin(_iq6 A); +extern _iq5 _IQ5asin(_iq5 A); +extern _iq4 _IQ4asin(_iq4 A); +extern _iq3 _IQ3asin(_iq3 A); +extern _iq2 _IQ2asin(_iq2 A); +extern _iq1 _IQ1asin(_iq1 A); + +#if GLOBAL_Q == 29 +#define _IQasin(A) _IQ29asin(A) +#endif +#if GLOBAL_Q == 28 +#define _IQasin(A) _IQ28asin(A) +#endif +#if GLOBAL_Q == 27 +#define _IQasin(A) _IQ27asin(A) +#endif +#if GLOBAL_Q == 26 +#define _IQasin(A) _IQ26asin(A) +#endif +#if GLOBAL_Q == 25 +#define _IQasin(A) _IQ25asin(A) +#endif +#if GLOBAL_Q == 24 +#define _IQasin(A) _IQ24asin(A) +#endif +#if GLOBAL_Q == 23 +#define _IQasin(A) _IQ23asin(A) +#endif +#if GLOBAL_Q == 22 +#define _IQasin(A) _IQ22asin(A) +#endif +#if GLOBAL_Q == 21 +#define _IQasin(A) _IQ21asin(A) +#endif +#if GLOBAL_Q == 20 +#define _IQasin(A) _IQ20asin(A) +#endif +#if GLOBAL_Q == 19 +#define _IQasin(A) _IQ19asin(A) +#endif +#if GLOBAL_Q == 18 +#define _IQasin(A) _IQ18asin(A) +#endif +#if GLOBAL_Q == 17 +#define _IQasin(A) _IQ17asin(A) +#endif +#if GLOBAL_Q == 16 +#define _IQasin(A) _IQ16asin(A) +#endif +#if GLOBAL_Q == 15 +#define _IQasin(A) _IQ15asin(A) +#endif +#if GLOBAL_Q == 14 +#define _IQasin(A) _IQ14asin(A) +#endif +#if GLOBAL_Q == 13 +#define _IQasin(A) _IQ13asin(A) +#endif +#if GLOBAL_Q == 12 +#define _IQasin(A) _IQ12asin(A) +#endif +#if GLOBAL_Q == 11 +#define _IQasin(A) _IQ11asin(A) +#endif +#if GLOBAL_Q == 10 +#define _IQasin(A) _IQ10asin(A) +#endif +#if GLOBAL_Q == 9 +#define _IQasin(A) _IQ9asin(A) +#endif +#if GLOBAL_Q == 8 +#define _IQasin(A) _IQ8asin(A) +#endif +#if GLOBAL_Q == 7 +#define _IQasin(A) _IQ7asin(A) +#endif +#if GLOBAL_Q == 6 +#define _IQasin(A) _IQ6asin(A) +#endif +#if GLOBAL_Q == 5 +#define _IQasin(A) _IQ5asin(A) +#endif +#if GLOBAL_Q == 4 +#define _IQasin(A) _IQ4asin(A) +#endif +#if GLOBAL_Q == 3 +#define _IQasin(A) _IQ3asin(A) +#endif +#if GLOBAL_Q == 2 +#define _IQasin(A) _IQ2asin(A) +#endif +#if GLOBAL_Q == 1 +#define _IQasin(A) _IQ1asin(A) +#endif + +//***************************************************************************** +// +// Computes the cos of an IQ number. +// +//***************************************************************************** +extern _iq29 _IQ29cos(_iq29 A); +extern _iq28 _IQ28cos(_iq28 A); +extern _iq27 _IQ27cos(_iq27 A); +extern _iq26 _IQ26cos(_iq26 A); +extern _iq25 _IQ25cos(_iq25 A); +extern _iq24 _IQ24cos(_iq24 A); +extern _iq23 _IQ23cos(_iq23 A); +extern _iq22 _IQ22cos(_iq22 A); +extern _iq21 _IQ21cos(_iq21 A); +extern _iq20 _IQ20cos(_iq20 A); +extern _iq19 _IQ19cos(_iq19 A); +extern _iq18 _IQ18cos(_iq18 A); +extern _iq17 _IQ17cos(_iq17 A); +extern _iq16 _IQ16cos(_iq16 A); +extern _iq15 _IQ15cos(_iq15 A); +extern _iq14 _IQ14cos(_iq14 A); +extern _iq13 _IQ13cos(_iq13 A); +extern _iq12 _IQ12cos(_iq12 A); +extern _iq11 _IQ11cos(_iq11 A); +extern _iq10 _IQ10cos(_iq10 A); +extern _iq9 _IQ9cos(_iq9 A); +extern _iq8 _IQ8cos(_iq8 A); +extern _iq7 _IQ7cos(_iq7 A); +extern _iq6 _IQ6cos(_iq6 A); +extern _iq5 _IQ5cos(_iq5 A); +extern _iq4 _IQ4cos(_iq4 A); +extern _iq3 _IQ3cos(_iq3 A); +extern _iq2 _IQ2cos(_iq2 A); +extern _iq1 _IQ1cos(_iq1 A); + +#if GLOBAL_Q == 29 +#define _IQcos(A) _IQ29cos(A) +#endif +#if GLOBAL_Q == 28 +#define _IQcos(A) _IQ28cos(A) +#endif +#if GLOBAL_Q == 27 +#define _IQcos(A) _IQ27cos(A) +#endif +#if GLOBAL_Q == 26 +#define _IQcos(A) _IQ26cos(A) +#endif +#if GLOBAL_Q == 25 +#define _IQcos(A) _IQ25cos(A) +#endif +#if GLOBAL_Q == 24 +#define _IQcos(A) _IQ24cos(A) +#endif +#if GLOBAL_Q == 23 +#define _IQcos(A) _IQ23cos(A) +#endif +#if GLOBAL_Q == 22 +#define _IQcos(A) _IQ22cos(A) +#endif +#if GLOBAL_Q == 21 +#define _IQcos(A) _IQ21cos(A) +#endif +#if GLOBAL_Q == 20 +#define _IQcos(A) _IQ20cos(A) +#endif +#if GLOBAL_Q == 19 +#define _IQcos(A) _IQ19cos(A) +#endif +#if GLOBAL_Q == 18 +#define _IQcos(A) _IQ18cos(A) +#endif +#if GLOBAL_Q == 17 +#define _IQcos(A) _IQ17cos(A) +#endif +#if GLOBAL_Q == 16 +#define _IQcos(A) _IQ16cos(A) +#endif +#if GLOBAL_Q == 15 +#define _IQcos(A) _IQ15cos(A) +#endif +#if GLOBAL_Q == 14 +#define _IQcos(A) _IQ14cos(A) +#endif +#if GLOBAL_Q == 13 +#define _IQcos(A) _IQ13cos(A) +#endif +#if GLOBAL_Q == 12 +#define _IQcos(A) _IQ12cos(A) +#endif +#if GLOBAL_Q == 11 +#define _IQcos(A) _IQ11cos(A) +#endif +#if GLOBAL_Q == 10 +#define _IQcos(A) _IQ10cos(A) +#endif +#if GLOBAL_Q == 9 +#define _IQcos(A) _IQ9cos(A) +#endif +#if GLOBAL_Q == 8 +#define _IQcos(A) _IQ8cos(A) +#endif +#if GLOBAL_Q == 7 +#define _IQcos(A) _IQ7cos(A) +#endif +#if GLOBAL_Q == 6 +#define _IQcos(A) _IQ6cos(A) +#endif +#if GLOBAL_Q == 5 +#define _IQcos(A) _IQ5cos(A) +#endif +#if GLOBAL_Q == 4 +#define _IQcos(A) _IQ4cos(A) +#endif +#if GLOBAL_Q == 3 +#define _IQcos(A) _IQ3cos(A) +#endif +#if GLOBAL_Q == 2 +#define _IQcos(A) _IQ2cos(A) +#endif +#if GLOBAL_Q == 1 +#define _IQcos(A) _IQ1cos(A) +#endif + +//***************************************************************************** +// +// Computes the cos of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +extern _iq30 _IQ30cosPU(_iq30 A); +extern _iq29 _IQ29cosPU(_iq29 A); +extern _iq28 _IQ28cosPU(_iq28 A); +extern _iq27 _IQ27cosPU(_iq27 A); +extern _iq26 _IQ26cosPU(_iq26 A); +extern _iq25 _IQ25cosPU(_iq25 A); +extern _iq24 _IQ24cosPU(_iq24 A); +extern _iq23 _IQ23cosPU(_iq23 A); +extern _iq22 _IQ22cosPU(_iq22 A); +extern _iq21 _IQ21cosPU(_iq21 A); +extern _iq20 _IQ20cosPU(_iq20 A); +extern _iq19 _IQ19cosPU(_iq19 A); +extern _iq18 _IQ18cosPU(_iq18 A); +extern _iq17 _IQ17cosPU(_iq17 A); +extern _iq16 _IQ16cosPU(_iq16 A); +extern _iq15 _IQ15cosPU(_iq15 A); +extern _iq14 _IQ14cosPU(_iq14 A); +extern _iq13 _IQ13cosPU(_iq13 A); +extern _iq12 _IQ12cosPU(_iq12 A); +extern _iq11 _IQ11cosPU(_iq11 A); +extern _iq10 _IQ10cosPU(_iq10 A); +extern _iq9 _IQ9cosPU(_iq9 A); +extern _iq8 _IQ8cosPU(_iq8 A); +extern _iq7 _IQ7cosPU(_iq7 A); +extern _iq6 _IQ6cosPU(_iq6 A); +extern _iq5 _IQ5cosPU(_iq5 A); +extern _iq4 _IQ4cosPU(_iq4 A); +extern _iq3 _IQ3cosPU(_iq3 A); +extern _iq2 _IQ2cosPU(_iq2 A); +extern _iq1 _IQ1cosPU(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQcosPU(A) _IQ30cosPU(A) +#endif +#if GLOBAL_Q == 29 +#define _IQcosPU(A) _IQ29cosPU(A) +#endif +#if GLOBAL_Q == 28 +#define _IQcosPU(A) _IQ28cosPU(A) +#endif +#if GLOBAL_Q == 27 +#define _IQcosPU(A) _IQ27cosPU(A) +#endif +#if GLOBAL_Q == 26 +#define _IQcosPU(A) _IQ26cosPU(A) +#endif +#if GLOBAL_Q == 25 +#define _IQcosPU(A) _IQ25cosPU(A) +#endif +#if GLOBAL_Q == 24 +#define _IQcosPU(A) _IQ24cosPU(A) +#endif +#if GLOBAL_Q == 23 +#define _IQcosPU(A) _IQ23cosPU(A) +#endif +#if GLOBAL_Q == 22 +#define _IQcosPU(A) _IQ22cosPU(A) +#endif +#if GLOBAL_Q == 21 +#define _IQcosPU(A) _IQ21cosPU(A) +#endif +#if GLOBAL_Q == 20 +#define _IQcosPU(A) _IQ20cosPU(A) +#endif +#if GLOBAL_Q == 19 +#define _IQcosPU(A) _IQ19cosPU(A) +#endif +#if GLOBAL_Q == 18 +#define _IQcosPU(A) _IQ18cosPU(A) +#endif +#if GLOBAL_Q == 17 +#define _IQcosPU(A) _IQ17cosPU(A) +#endif +#if GLOBAL_Q == 16 +#define _IQcosPU(A) _IQ16cosPU(A) +#endif +#if GLOBAL_Q == 15 +#define _IQcosPU(A) _IQ15cosPU(A) +#endif +#if GLOBAL_Q == 14 +#define _IQcosPU(A) _IQ14cosPU(A) +#endif +#if GLOBAL_Q == 13 +#define _IQcosPU(A) _IQ13cosPU(A) +#endif +#if GLOBAL_Q == 12 +#define _IQcosPU(A) _IQ12cosPU(A) +#endif +#if GLOBAL_Q == 11 +#define _IQcosPU(A) _IQ11cosPU(A) +#endif +#if GLOBAL_Q == 10 +#define _IQcosPU(A) _IQ10cosPU(A) +#endif +#if GLOBAL_Q == 9 +#define _IQcosPU(A) _IQ9cosPU(A) +#endif +#if GLOBAL_Q == 8 +#define _IQcosPU(A) _IQ8cosPU(A) +#endif +#if GLOBAL_Q == 7 +#define _IQcosPU(A) _IQ7cosPU(A) +#endif +#if GLOBAL_Q == 6 +#define _IQcosPU(A) _IQ6cosPU(A) +#endif +#if GLOBAL_Q == 5 +#define _IQcosPU(A) _IQ5cosPU(A) +#endif +#if GLOBAL_Q == 4 +#define _IQcosPU(A) _IQ4cosPU(A) +#endif +#if GLOBAL_Q == 3 +#define _IQcosPU(A) _IQ3cosPU(A) +#endif +#if GLOBAL_Q == 2 +#define _IQcosPU(A) _IQ2cosPU(A) +#endif +#if GLOBAL_Q == 1 +#define _IQcosPU(A) _IQ1cosPU(A) +#endif + +//***************************************************************************** +// +// Computes the arccos of an IQ number. +// +//***************************************************************************** +#define _IQ29acos(A) (_IQ29(1.570796327) - _IQ29asin(A)) +#define _IQ28acos(A) (_IQ28(1.570796327) - _IQ28asin(A)) +#define _IQ27acos(A) (_IQ27(1.570796327) - _IQ27asin(A)) +#define _IQ26acos(A) (_IQ26(1.570796327) - _IQ26asin(A)) +#define _IQ25acos(A) (_IQ25(1.570796327) - _IQ25asin(A)) +#define _IQ24acos(A) (_IQ24(1.570796327) - _IQ24asin(A)) +#define _IQ23acos(A) (_IQ23(1.570796327) - _IQ23asin(A)) +#define _IQ22acos(A) (_IQ22(1.570796327) - _IQ22asin(A)) +#define _IQ21acos(A) (_IQ21(1.570796327) - _IQ21asin(A)) +#define _IQ20acos(A) (_IQ20(1.570796327) - _IQ20asin(A)) +#define _IQ19acos(A) (_IQ19(1.570796327) - _IQ19asin(A)) +#define _IQ18acos(A) (_IQ18(1.570796327) - _IQ18asin(A)) +#define _IQ17acos(A) (_IQ17(1.570796327) - _IQ17asin(A)) +#define _IQ16acos(A) (_IQ16(1.570796327) - _IQ16asin(A)) +#define _IQ15acos(A) (_IQ15(1.570796327) - _IQ15asin(A)) +#define _IQ14acos(A) (_IQ14(1.570796327) - _IQ14asin(A)) +#define _IQ13acos(A) (_IQ13(1.570796327) - _IQ13asin(A)) +#define _IQ12acos(A) (_IQ12(1.570796327) - _IQ12asin(A)) +#define _IQ11acos(A) (_IQ11(1.570796327) - _IQ11asin(A)) +#define _IQ10acos(A) (_IQ10(1.570796327) - _IQ10asin(A)) +#define _IQ9acos(A) (_IQ9(1.570796327) - _IQ9asin(A)) +#define _IQ8acos(A) (_IQ8(1.570796327) - _IQ8asin(A)) +#define _IQ7acos(A) (_IQ7(1.570796327) - _IQ7asin(A)) +#define _IQ6acos(A) (_IQ6(1.570796327) - _IQ6asin(A)) +#define _IQ5acos(A) (_IQ5(1.570796327) - _IQ5asin(A)) +#define _IQ4acos(A) (_IQ4(1.570796327) - _IQ4asin(A)) +#define _IQ3acos(A) (_IQ3(1.570796327) - _IQ3asin(A)) +#define _IQ2acos(A) (_IQ2(1.570796327) - _IQ2asin(A)) +#define _IQ1acos(A) (_IQ1(1.570796327) - _IQ1asin(A)) + +#if GLOBAL_Q == 29 +#define _IQacos(A) _IQ29acos(A) +#endif +#if GLOBAL_Q == 28 +#define _IQacos(A) _IQ28acos(A) +#endif +#if GLOBAL_Q == 27 +#define _IQacos(A) _IQ27acos(A) +#endif +#if GLOBAL_Q == 26 +#define _IQacos(A) _IQ26acos(A) +#endif +#if GLOBAL_Q == 25 +#define _IQacos(A) _IQ25acos(A) +#endif +#if GLOBAL_Q == 24 +#define _IQacos(A) _IQ24acos(A) +#endif +#if GLOBAL_Q == 23 +#define _IQacos(A) _IQ23acos(A) +#endif +#if GLOBAL_Q == 22 +#define _IQacos(A) _IQ22acos(A) +#endif +#if GLOBAL_Q == 21 +#define _IQacos(A) _IQ21acos(A) +#endif +#if GLOBAL_Q == 20 +#define _IQacos(A) _IQ20acos(A) +#endif +#if GLOBAL_Q == 19 +#define _IQacos(A) _IQ19acos(A) +#endif +#if GLOBAL_Q == 18 +#define _IQacos(A) _IQ18acos(A) +#endif +#if GLOBAL_Q == 17 +#define _IQacos(A) _IQ17acos(A) +#endif +#if GLOBAL_Q == 16 +#define _IQacos(A) _IQ16acos(A) +#endif +#if GLOBAL_Q == 15 +#define _IQacos(A) _IQ15acos(A) +#endif +#if GLOBAL_Q == 14 +#define _IQacos(A) _IQ14acos(A) +#endif +#if GLOBAL_Q == 13 +#define _IQacos(A) _IQ13acos(A) +#endif +#if GLOBAL_Q == 12 +#define _IQacos(A) _IQ12acos(A) +#endif +#if GLOBAL_Q == 11 +#define _IQacos(A) _IQ11acos(A) +#endif +#if GLOBAL_Q == 10 +#define _IQacos(A) _IQ10acos(A) +#endif +#if GLOBAL_Q == 9 +#define _IQacos(A) _IQ9acos(A) +#endif +#if GLOBAL_Q == 8 +#define _IQacos(A) _IQ8acos(A) +#endif +#if GLOBAL_Q == 7 +#define _IQacos(A) _IQ7acos(A) +#endif +#if GLOBAL_Q == 6 +#define _IQacos(A) _IQ6acos(A) +#endif +#if GLOBAL_Q == 5 +#define _IQacos(A) _IQ5acos(A) +#endif +#if GLOBAL_Q == 4 +#define _IQacos(A) _IQ4acos(A) +#endif +#if GLOBAL_Q == 3 +#define _IQacos(A) _IQ3acos(A) +#endif +#if GLOBAL_Q == 2 +#define _IQacos(A) _IQ2acos(A) +#endif +#if GLOBAL_Q == 1 +#define _IQacos(A) _IQ1acos(A) +#endif + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers. +// +//***************************************************************************** +extern _iq29 _IQ29atan2(_iq29 A, _iq29 B); +extern _iq28 _IQ28atan2(_iq28 A, _iq28 B); +extern _iq27 _IQ27atan2(_iq27 A, _iq27 B); +extern _iq26 _IQ26atan2(_iq26 A, _iq26 B); +extern _iq25 _IQ25atan2(_iq25 A, _iq25 B); +extern _iq24 _IQ24atan2(_iq24 A, _iq24 B); +extern _iq23 _IQ23atan2(_iq23 A, _iq23 B); +extern _iq22 _IQ22atan2(_iq22 A, _iq22 B); +extern _iq21 _IQ21atan2(_iq21 A, _iq21 B); +extern _iq20 _IQ20atan2(_iq20 A, _iq20 B); +extern _iq19 _IQ19atan2(_iq19 A, _iq19 B); +extern _iq18 _IQ18atan2(_iq18 A, _iq18 B); +extern _iq17 _IQ17atan2(_iq17 A, _iq17 B); +extern _iq16 _IQ16atan2(_iq16 A, _iq16 B); +extern _iq15 _IQ15atan2(_iq15 A, _iq15 B); +extern _iq14 _IQ14atan2(_iq14 A, _iq14 B); +extern _iq13 _IQ13atan2(_iq13 A, _iq13 B); +extern _iq12 _IQ12atan2(_iq12 A, _iq12 B); +extern _iq11 _IQ11atan2(_iq11 A, _iq11 B); +extern _iq10 _IQ10atan2(_iq10 A, _iq10 B); +extern _iq9 _IQ9atan2(_iq9 A, _iq9 B); +extern _iq8 _IQ8atan2(_iq8 A, _iq8 B); +extern _iq7 _IQ7atan2(_iq7 A, _iq7 B); +extern _iq6 _IQ6atan2(_iq6 A, _iq6 B); +extern _iq5 _IQ5atan2(_iq5 A, _iq5 B); +extern _iq4 _IQ4atan2(_iq4 A, _iq4 B); +extern _iq3 _IQ3atan2(_iq3 A, _iq3 B); +extern _iq2 _IQ2atan2(_iq2 A, _iq2 B); +extern _iq1 _IQ1atan2(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 29 +#define _IQatan2(A, B) _IQ29atan2(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQatan2(A, B) _IQ28atan2(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQatan2(A, B) _IQ27atan2(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQatan2(A, B) _IQ26atan2(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQatan2(A, B) _IQ25atan2(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQatan2(A, B) _IQ24atan2(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQatan2(A, B) _IQ23atan2(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQatan2(A, B) _IQ22atan2(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQatan2(A, B) _IQ21atan2(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQatan2(A, B) _IQ20atan2(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQatan2(A, B) _IQ19atan2(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQatan2(A, B) _IQ18atan2(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQatan2(A, B) _IQ17atan2(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQatan2(A, B) _IQ16atan2(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQatan2(A, B) _IQ15atan2(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQatan2(A, B) _IQ14atan2(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQatan2(A, B) _IQ13atan2(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQatan2(A, B) _IQ12atan2(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQatan2(A, B) _IQ11atan2(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQatan2(A, B) _IQ10atan2(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQatan2(A, B) _IQ9atan2(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQatan2(A, B) _IQ8atan2(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQatan2(A, B) _IQ7atan2(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQatan2(A, B) _IQ6atan2(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQatan2(A, B) _IQ5atan2(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQatan2(A, B) _IQ4atan2(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQatan2(A, B) _IQ3atan2(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQatan2(A, B) _IQ2atan2(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQatan2(A, B) _IQ1atan2(A, B) +#endif + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers, returning +// the value in cycles per unit instead of radians. +// +//***************************************************************************** +extern _iq30 _IQ30atan2PU(_iq30 A, _iq30 B); +extern _iq29 _IQ29atan2PU(_iq29 A, _iq29 B); +extern _iq28 _IQ28atan2PU(_iq28 A, _iq28 B); +extern _iq27 _IQ27atan2PU(_iq27 A, _iq27 B); +extern _iq26 _IQ26atan2PU(_iq26 A, _iq26 B); +extern _iq25 _IQ25atan2PU(_iq25 A, _iq25 B); +extern _iq24 _IQ24atan2PU(_iq24 A, _iq24 B); +extern _iq23 _IQ23atan2PU(_iq23 A, _iq23 B); +extern _iq22 _IQ22atan2PU(_iq22 A, _iq22 B); +extern _iq21 _IQ21atan2PU(_iq21 A, _iq21 B); +extern _iq20 _IQ20atan2PU(_iq20 A, _iq20 B); +extern _iq19 _IQ19atan2PU(_iq19 A, _iq19 B); +extern _iq18 _IQ18atan2PU(_iq18 A, _iq18 B); +extern _iq17 _IQ17atan2PU(_iq17 A, _iq17 B); +extern _iq16 _IQ16atan2PU(_iq16 A, _iq16 B); +extern _iq15 _IQ15atan2PU(_iq15 A, _iq15 B); +extern _iq14 _IQ14atan2PU(_iq14 A, _iq14 B); +extern _iq13 _IQ13atan2PU(_iq13 A, _iq13 B); +extern _iq12 _IQ12atan2PU(_iq12 A, _iq12 B); +extern _iq11 _IQ11atan2PU(_iq11 A, _iq11 B); +extern _iq10 _IQ10atan2PU(_iq10 A, _iq10 B); +extern _iq9 _IQ9atan2PU(_iq9 A, _iq9 B); +extern _iq8 _IQ8atan2PU(_iq8 A, _iq8 B); +extern _iq7 _IQ7atan2PU(_iq7 A, _iq7 B); +extern _iq6 _IQ6atan2PU(_iq6 A, _iq6 B); +extern _iq5 _IQ5atan2PU(_iq5 A, _iq5 B); +extern _iq4 _IQ4atan2PU(_iq4 A, _iq4 B); +extern _iq3 _IQ3atan2PU(_iq3 A, _iq3 B); +extern _iq2 _IQ2atan2PU(_iq2 A, _iq2 B); +extern _iq1 _IQ1atan2PU(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQatan2PU(A, B) _IQ30atan2PU(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQatan2PU(A, B) _IQ29atan2PU(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQatan2PU(A, B) _IQ28atan2PU(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQatan2PU(A, B) _IQ27atan2PU(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQatan2PU(A, B) _IQ26atan2PU(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQatan2PU(A, B) _IQ25atan2PU(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQatan2PU(A, B) _IQ24atan2PU(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQatan2PU(A, B) _IQ23atan2PU(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQatan2PU(A, B) _IQ22atan2PU(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQatan2PU(A, B) _IQ21atan2PU(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQatan2PU(A, B) _IQ20atan2PU(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQatan2PU(A, B) _IQ19atan2PU(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQatan2PU(A, B) _IQ18atan2PU(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQatan2PU(A, B) _IQ17atan2PU(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQatan2PU(A, B) _IQ16atan2PU(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQatan2PU(A, B) _IQ15atan2PU(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQatan2PU(A, B) _IQ14atan2PU(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQatan2PU(A, B) _IQ13atan2PU(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQatan2PU(A, B) _IQ12atan2PU(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQatan2PU(A, B) _IQ11atan2PU(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQatan2PU(A, B) _IQ10atan2PU(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQatan2PU(A, B) _IQ9atan2PU(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQatan2PU(A, B) _IQ8atan2PU(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQatan2PU(A, B) _IQ7atan2PU(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQatan2PU(A, B) _IQ6atan2PU(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQatan2PU(A, B) _IQ5atan2PU(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQatan2PU(A, B) _IQ4atan2PU(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQatan2PU(A, B) _IQ3atan2PU(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQatan2PU(A, B) _IQ2atan2PU(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQatan2PU(A, B) _IQ1atan2PU(A, B) +#endif + +//***************************************************************************** +// +// Computes the arctan of an IQ number. +// +//***************************************************************************** +#define _IQ29atan(A) _IQ29atan2(A, _IQ29(1.0)) +#define _IQ28atan(A) _IQ28atan2(A, _IQ28(1.0)) +#define _IQ27atan(A) _IQ27atan2(A, _IQ27(1.0)) +#define _IQ26atan(A) _IQ26atan2(A, _IQ26(1.0)) +#define _IQ25atan(A) _IQ25atan2(A, _IQ25(1.0)) +#define _IQ24atan(A) _IQ24atan2(A, _IQ24(1.0)) +#define _IQ23atan(A) _IQ23atan2(A, _IQ23(1.0)) +#define _IQ22atan(A) _IQ22atan2(A, _IQ22(1.0)) +#define _IQ21atan(A) _IQ21atan2(A, _IQ21(1.0)) +#define _IQ20atan(A) _IQ20atan2(A, _IQ20(1.0)) +#define _IQ19atan(A) _IQ19atan2(A, _IQ19(1.0)) +#define _IQ18atan(A) _IQ18atan2(A, _IQ18(1.0)) +#define _IQ17atan(A) _IQ17atan2(A, _IQ17(1.0)) +#define _IQ16atan(A) _IQ16atan2(A, _IQ16(1.0)) +#define _IQ15atan(A) _IQ15atan2(A, _IQ15(1.0)) +#define _IQ14atan(A) _IQ14atan2(A, _IQ14(1.0)) +#define _IQ13atan(A) _IQ13atan2(A, _IQ13(1.0)) +#define _IQ12atan(A) _IQ12atan2(A, _IQ12(1.0)) +#define _IQ11atan(A) _IQ11atan2(A, _IQ11(1.0)) +#define _IQ10atan(A) _IQ10atan2(A, _IQ10(1.0)) +#define _IQ9atan(A) _IQ9atan2(A, _IQ9(1.0)) +#define _IQ8atan(A) _IQ8atan2(A, _IQ8(1.0)) +#define _IQ7atan(A) _IQ7atan2(A, _IQ7(1.0)) +#define _IQ6atan(A) _IQ6atan2(A, _IQ6(1.0)) +#define _IQ5atan(A) _IQ5atan2(A, _IQ5(1.0)) +#define _IQ4atan(A) _IQ4atan2(A, _IQ4(1.0)) +#define _IQ3atan(A) _IQ3atan2(A, _IQ3(1.0)) +#define _IQ2atan(A) _IQ2atan2(A, _IQ2(1.0)) +#define _IQ1atan(A) _IQ1atan2(A, _IQ1(1.0)) + +#if GLOBAL_Q == 29 +#define _IQatan(A) _IQ29atan2(A, _IQ29(1.0)) +#endif +#if GLOBAL_Q == 28 +#define _IQatan(A) _IQ28atan2(A, _IQ28(1.0)) +#endif +#if GLOBAL_Q == 27 +#define _IQatan(A) _IQ27atan2(A, _IQ27(1.0)) +#endif +#if GLOBAL_Q == 26 +#define _IQatan(A) _IQ26atan2(A, _IQ26(1.0)) +#endif +#if GLOBAL_Q == 25 +#define _IQatan(A) _IQ25atan2(A, _IQ25(1.0)) +#endif +#if GLOBAL_Q == 24 +#define _IQatan(A) _IQ24atan2(A, _IQ24(1.0)) +#endif +#if GLOBAL_Q == 23 +#define _IQatan(A) _IQ23atan2(A, _IQ23(1.0)) +#endif +#if GLOBAL_Q == 22 +#define _IQatan(A) _IQ22atan2(A, _IQ22(1.0)) +#endif +#if GLOBAL_Q == 21 +#define _IQatan(A) _IQ21atan2(A, _IQ21(1.0)) +#endif +#if GLOBAL_Q == 20 +#define _IQatan(A) _IQ20atan2(A, _IQ20(1.0)) +#endif +#if GLOBAL_Q == 19 +#define _IQatan(A) _IQ19atan2(A, _IQ19(1.0)) +#endif +#if GLOBAL_Q == 18 +#define _IQatan(A) _IQ18atan2(A, _IQ18(1.0)) +#endif +#if GLOBAL_Q == 17 +#define _IQatan(A) _IQ17atan2(A, _IQ17(1.0)) +#endif +#if GLOBAL_Q == 16 +#define _IQatan(A) _IQ16atan2(A, _IQ16(1.0)) +#endif +#if GLOBAL_Q == 15 +#define _IQatan(A) _IQ15atan2(A, _IQ15(1.0)) +#endif +#if GLOBAL_Q == 14 +#define _IQatan(A) _IQ14atan2(A, _IQ14(1.0)) +#endif +#if GLOBAL_Q == 13 +#define _IQatan(A) _IQ13atan2(A, _IQ13(1.0)) +#endif +#if GLOBAL_Q == 12 +#define _IQatan(A) _IQ12atan2(A, _IQ12(1.0)) +#endif +#if GLOBAL_Q == 11 +#define _IQatan(A) _IQ11atan2(A, _IQ11(1.0)) +#endif +#if GLOBAL_Q == 10 +#define _IQatan(A) _IQ10atan2(A, _IQ10(1.0)) +#endif +#if GLOBAL_Q == 9 +#define _IQatan(A) _IQ9atan2(A, _IQ9(1.0)) +#endif +#if GLOBAL_Q == 8 +#define _IQatan(A) _IQ8atan2(A, _IQ8(1.0)) +#endif +#if GLOBAL_Q == 7 +#define _IQatan(A) _IQ7atan2(A, _IQ7(1.0)) +#endif +#if GLOBAL_Q == 6 +#define _IQatan(A) _IQ6atan2(A, _IQ6(1.0)) +#endif +#if GLOBAL_Q == 5 +#define _IQatan(A) _IQ5atan2(A, _IQ5(1.0)) +#endif +#if GLOBAL_Q == 4 +#define _IQatan(A) _IQ4atan2(A, _IQ4(1.0)) +#endif +#if GLOBAL_Q == 3 +#define _IQatan(A) _IQ3atan2(A, _IQ3(1.0)) +#endif +#if GLOBAL_Q == 2 +#define _IQatan(A) _IQ2atan2(A, _IQ2(1.0)) +#endif +#if GLOBAL_Q == 1 +#define _IQatan(A) _IQ1atan2(A, _IQ1(1.0)) +#endif + +//***************************************************************************** +// +// Computes the square root of an IQ number. +// +//***************************************************************************** +extern _iq30 _IQ30sqrt(_iq30 A); +extern _iq29 _IQ29sqrt(_iq29 A); +extern _iq28 _IQ28sqrt(_iq28 A); +extern _iq27 _IQ27sqrt(_iq27 A); +extern _iq26 _IQ26sqrt(_iq26 A); +extern _iq25 _IQ25sqrt(_iq25 A); +extern _iq24 _IQ24sqrt(_iq24 A); +extern _iq23 _IQ23sqrt(_iq23 A); +extern _iq22 _IQ22sqrt(_iq22 A); +extern _iq21 _IQ21sqrt(_iq21 A); +extern _iq20 _IQ20sqrt(_iq20 A); +extern _iq19 _IQ19sqrt(_iq19 A); +extern _iq18 _IQ18sqrt(_iq18 A); +extern _iq17 _IQ17sqrt(_iq17 A); +extern _iq16 _IQ16sqrt(_iq16 A); +extern _iq15 _IQ15sqrt(_iq15 A); +extern _iq14 _IQ14sqrt(_iq14 A); +extern _iq13 _IQ13sqrt(_iq13 A); +extern _iq12 _IQ12sqrt(_iq12 A); +extern _iq11 _IQ11sqrt(_iq11 A); +extern _iq10 _IQ10sqrt(_iq10 A); +extern _iq9 _IQ9sqrt(_iq9 A); +extern _iq8 _IQ8sqrt(_iq8 A); +extern _iq7 _IQ7sqrt(_iq7 A); +extern _iq6 _IQ6sqrt(_iq6 A); +extern _iq5 _IQ5sqrt(_iq5 A); +extern _iq4 _IQ4sqrt(_iq4 A); +extern _iq3 _IQ3sqrt(_iq3 A); +extern _iq2 _IQ2sqrt(_iq2 A); +extern _iq1 _IQ1sqrt(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQsqrt(A) _IQ30sqrt(A) +#endif +#if GLOBAL_Q == 29 +#define _IQsqrt(A) _IQ29sqrt(A) +#endif +#if GLOBAL_Q == 28 +#define _IQsqrt(A) _IQ28sqrt(A) +#endif +#if GLOBAL_Q == 27 +#define _IQsqrt(A) _IQ27sqrt(A) +#endif +#if GLOBAL_Q == 26 +#define _IQsqrt(A) _IQ26sqrt(A) +#endif +#if GLOBAL_Q == 25 +#define _IQsqrt(A) _IQ25sqrt(A) +#endif +#if GLOBAL_Q == 24 +#define _IQsqrt(A) _IQ24sqrt(A) +#endif +#if GLOBAL_Q == 23 +#define _IQsqrt(A) _IQ23sqrt(A) +#endif +#if GLOBAL_Q == 22 +#define _IQsqrt(A) _IQ22sqrt(A) +#endif +#if GLOBAL_Q == 21 +#define _IQsqrt(A) _IQ21sqrt(A) +#endif +#if GLOBAL_Q == 20 +#define _IQsqrt(A) _IQ20sqrt(A) +#endif +#if GLOBAL_Q == 19 +#define _IQsqrt(A) _IQ19sqrt(A) +#endif +#if GLOBAL_Q == 18 +#define _IQsqrt(A) _IQ18sqrt(A) +#endif +#if GLOBAL_Q == 17 +#define _IQsqrt(A) _IQ17sqrt(A) +#endif +#if GLOBAL_Q == 16 +#define _IQsqrt(A) _IQ16sqrt(A) +#endif +#if GLOBAL_Q == 15 +#define _IQsqrt(A) _IQ15sqrt(A) +#endif +#if GLOBAL_Q == 14 +#define _IQsqrt(A) _IQ14sqrt(A) +#endif +#if GLOBAL_Q == 13 +#define _IQsqrt(A) _IQ13sqrt(A) +#endif +#if GLOBAL_Q == 12 +#define _IQsqrt(A) _IQ12sqrt(A) +#endif +#if GLOBAL_Q == 11 +#define _IQsqrt(A) _IQ11sqrt(A) +#endif +#if GLOBAL_Q == 10 +#define _IQsqrt(A) _IQ10sqrt(A) +#endif +#if GLOBAL_Q == 9 +#define _IQsqrt(A) _IQ9sqrt(A) +#endif +#if GLOBAL_Q == 8 +#define _IQsqrt(A) _IQ8sqrt(A) +#endif +#if GLOBAL_Q == 7 +#define _IQsqrt(A) _IQ7sqrt(A) +#endif +#if GLOBAL_Q == 6 +#define _IQsqrt(A) _IQ6sqrt(A) +#endif +#if GLOBAL_Q == 5 +#define _IQsqrt(A) _IQ5sqrt(A) +#endif +#if GLOBAL_Q == 4 +#define _IQsqrt(A) _IQ4sqrt(A) +#endif +#if GLOBAL_Q == 3 +#define _IQsqrt(A) _IQ3sqrt(A) +#endif +#if GLOBAL_Q == 2 +#define _IQsqrt(A) _IQ2sqrt(A) +#endif +#if GLOBAL_Q == 1 +#define _IQsqrt(A) _IQ1sqrt(A) +#endif + +//***************************************************************************** +// +// Computes 1 over the square root of an IQ number. +// +//***************************************************************************** +extern _iq30 _IQ30isqrt(_iq30 A); +extern _iq29 _IQ29isqrt(_iq29 A); +extern _iq28 _IQ28isqrt(_iq28 A); +extern _iq27 _IQ27isqrt(_iq27 A); +extern _iq26 _IQ26isqrt(_iq26 A); +extern _iq25 _IQ25isqrt(_iq25 A); +extern _iq24 _IQ24isqrt(_iq24 A); +extern _iq23 _IQ23isqrt(_iq23 A); +extern _iq22 _IQ22isqrt(_iq22 A); +extern _iq21 _IQ21isqrt(_iq21 A); +extern _iq20 _IQ20isqrt(_iq20 A); +extern _iq19 _IQ19isqrt(_iq19 A); +extern _iq18 _IQ18isqrt(_iq18 A); +extern _iq17 _IQ17isqrt(_iq17 A); +extern _iq16 _IQ16isqrt(_iq16 A); +extern _iq15 _IQ15isqrt(_iq15 A); +extern _iq14 _IQ14isqrt(_iq14 A); +extern _iq13 _IQ13isqrt(_iq13 A); +extern _iq12 _IQ12isqrt(_iq12 A); +extern _iq11 _IQ11isqrt(_iq11 A); +extern _iq10 _IQ10isqrt(_iq10 A); +extern _iq9 _IQ9isqrt(_iq9 A); +extern _iq8 _IQ8isqrt(_iq8 A); +extern _iq7 _IQ7isqrt(_iq7 A); +extern _iq6 _IQ6isqrt(_iq6 A); +extern _iq5 _IQ5isqrt(_iq5 A); +extern _iq4 _IQ4isqrt(_iq4 A); +extern _iq3 _IQ3isqrt(_iq3 A); +extern _iq2 _IQ2isqrt(_iq2 A); +extern _iq1 _IQ1isqrt(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQisqrt(A) _IQ30isqrt(A) +#endif +#if GLOBAL_Q == 29 +#define _IQisqrt(A) _IQ29isqrt(A) +#endif +#if GLOBAL_Q == 28 +#define _IQisqrt(A) _IQ28isqrt(A) +#endif +#if GLOBAL_Q == 27 +#define _IQisqrt(A) _IQ27isqrt(A) +#endif +#if GLOBAL_Q == 26 +#define _IQisqrt(A) _IQ26isqrt(A) +#endif +#if GLOBAL_Q == 25 +#define _IQisqrt(A) _IQ25isqrt(A) +#endif +#if GLOBAL_Q == 24 +#define _IQisqrt(A) _IQ24isqrt(A) +#endif +#if GLOBAL_Q == 23 +#define _IQisqrt(A) _IQ23isqrt(A) +#endif +#if GLOBAL_Q == 22 +#define _IQisqrt(A) _IQ22isqrt(A) +#endif +#if GLOBAL_Q == 21 +#define _IQisqrt(A) _IQ21isqrt(A) +#endif +#if GLOBAL_Q == 20 +#define _IQisqrt(A) _IQ20isqrt(A) +#endif +#if GLOBAL_Q == 19 +#define _IQisqrt(A) _IQ19isqrt(A) +#endif +#if GLOBAL_Q == 18 +#define _IQisqrt(A) _IQ18isqrt(A) +#endif +#if GLOBAL_Q == 17 +#define _IQisqrt(A) _IQ17isqrt(A) +#endif +#if GLOBAL_Q == 16 +#define _IQisqrt(A) _IQ16isqrt(A) +#endif +#if GLOBAL_Q == 15 +#define _IQisqrt(A) _IQ15isqrt(A) +#endif +#if GLOBAL_Q == 14 +#define _IQisqrt(A) _IQ14isqrt(A) +#endif +#if GLOBAL_Q == 13 +#define _IQisqrt(A) _IQ13isqrt(A) +#endif +#if GLOBAL_Q == 12 +#define _IQisqrt(A) _IQ12isqrt(A) +#endif +#if GLOBAL_Q == 11 +#define _IQisqrt(A) _IQ11isqrt(A) +#endif +#if GLOBAL_Q == 10 +#define _IQisqrt(A) _IQ10isqrt(A) +#endif +#if GLOBAL_Q == 9 +#define _IQisqrt(A) _IQ9isqrt(A) +#endif +#if GLOBAL_Q == 8 +#define _IQisqrt(A) _IQ8isqrt(A) +#endif +#if GLOBAL_Q == 7 +#define _IQisqrt(A) _IQ7isqrt(A) +#endif +#if GLOBAL_Q == 6 +#define _IQisqrt(A) _IQ6isqrt(A) +#endif +#if GLOBAL_Q == 5 +#define _IQisqrt(A) _IQ5isqrt(A) +#endif +#if GLOBAL_Q == 4 +#define _IQisqrt(A) _IQ4isqrt(A) +#endif +#if GLOBAL_Q == 3 +#define _IQisqrt(A) _IQ3isqrt(A) +#endif +#if GLOBAL_Q == 2 +#define _IQisqrt(A) _IQ2isqrt(A) +#endif +#if GLOBAL_Q == 1 +#define _IQisqrt(A) _IQ1isqrt(A) +#endif + +//***************************************************************************** +// +// Computes e^x of an IQ number. +// +//***************************************************************************** +extern _iq30 _IQ30exp(_iq30 A); +extern _iq29 _IQ29exp(_iq29 A); +extern _iq28 _IQ28exp(_iq28 A); +extern _iq27 _IQ27exp(_iq27 A); +extern _iq26 _IQ26exp(_iq26 A); +extern _iq25 _IQ25exp(_iq25 A); +extern _iq24 _IQ24exp(_iq24 A); +extern _iq23 _IQ23exp(_iq23 A); +extern _iq22 _IQ22exp(_iq22 A); +extern _iq21 _IQ21exp(_iq21 A); +extern _iq20 _IQ20exp(_iq20 A); +extern _iq19 _IQ19exp(_iq19 A); +extern _iq18 _IQ18exp(_iq18 A); +extern _iq17 _IQ17exp(_iq17 A); +extern _iq16 _IQ16exp(_iq16 A); +extern _iq15 _IQ15exp(_iq15 A); +extern _iq14 _IQ14exp(_iq14 A); +extern _iq13 _IQ13exp(_iq13 A); +extern _iq12 _IQ12exp(_iq12 A); +extern _iq11 _IQ11exp(_iq11 A); +extern _iq10 _IQ10exp(_iq10 A); +extern _iq9 _IQ9exp(_iq9 A); +extern _iq8 _IQ8exp(_iq8 A); +extern _iq7 _IQ7exp(_iq7 A); +extern _iq6 _IQ6exp(_iq6 A); +extern _iq5 _IQ5exp(_iq5 A); +extern _iq4 _IQ4exp(_iq4 A); +extern _iq3 _IQ3exp(_iq3 A); +extern _iq2 _IQ2exp(_iq2 A); +extern _iq1 _IQ1exp(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQexp(A) _IQ30exp(A) +#endif +#if GLOBAL_Q == 29 +#define _IQexp(A) _IQ29exp(A) +#endif +#if GLOBAL_Q == 28 +#define _IQexp(A) _IQ28exp(A) +#endif +#if GLOBAL_Q == 27 +#define _IQexp(A) _IQ27exp(A) +#endif +#if GLOBAL_Q == 26 +#define _IQexp(A) _IQ26exp(A) +#endif +#if GLOBAL_Q == 25 +#define _IQexp(A) _IQ25exp(A) +#endif +#if GLOBAL_Q == 24 +#define _IQexp(A) _IQ24exp(A) +#endif +#if GLOBAL_Q == 23 +#define _IQexp(A) _IQ23exp(A) +#endif +#if GLOBAL_Q == 22 +#define _IQexp(A) _IQ22exp(A) +#endif +#if GLOBAL_Q == 21 +#define _IQexp(A) _IQ21exp(A) +#endif +#if GLOBAL_Q == 20 +#define _IQexp(A) _IQ20exp(A) +#endif +#if GLOBAL_Q == 19 +#define _IQexp(A) _IQ19exp(A) +#endif +#if GLOBAL_Q == 18 +#define _IQexp(A) _IQ18exp(A) +#endif +#if GLOBAL_Q == 17 +#define _IQexp(A) _IQ17exp(A) +#endif +#if GLOBAL_Q == 16 +#define _IQexp(A) _IQ16exp(A) +#endif +#if GLOBAL_Q == 15 +#define _IQexp(A) _IQ15exp(A) +#endif +#if GLOBAL_Q == 14 +#define _IQexp(A) _IQ14exp(A) +#endif +#if GLOBAL_Q == 13 +#define _IQexp(A) _IQ13exp(A) +#endif +#if GLOBAL_Q == 12 +#define _IQexp(A) _IQ12exp(A) +#endif +#if GLOBAL_Q == 11 +#define _IQexp(A) _IQ11exp(A) +#endif +#if GLOBAL_Q == 10 +#define _IQexp(A) _IQ10exp(A) +#endif +#if GLOBAL_Q == 9 +#define _IQexp(A) _IQ9exp(A) +#endif +#if GLOBAL_Q == 8 +#define _IQexp(A) _IQ8exp(A) +#endif +#if GLOBAL_Q == 7 +#define _IQexp(A) _IQ7exp(A) +#endif +#if GLOBAL_Q == 6 +#define _IQexp(A) _IQ6exp(A) +#endif +#if GLOBAL_Q == 5 +#define _IQexp(A) _IQ5exp(A) +#endif +#if GLOBAL_Q == 4 +#define _IQexp(A) _IQ4exp(A) +#endif +#if GLOBAL_Q == 3 +#define _IQexp(A) _IQ3exp(A) +#endif +#if GLOBAL_Q == 2 +#define _IQexp(A) _IQ2exp(A) +#endif +#if GLOBAL_Q == 1 +#define _IQexp(A) _IQ1exp(A) +#endif + +//***************************************************************************** +// +// Computes 2^x of an IQ number. +// +//***************************************************************************** +extern _iq30 _IQ30exp2(_iq30 A); +extern _iq29 _IQ29exp2(_iq29 A); +extern _iq28 _IQ28exp2(_iq28 A); +extern _iq27 _IQ27exp2(_iq27 A); +extern _iq26 _IQ26exp2(_iq26 A); +extern _iq25 _IQ25exp2(_iq25 A); +extern _iq24 _IQ24exp2(_iq24 A); +extern _iq23 _IQ23exp2(_iq23 A); +extern _iq22 _IQ22exp2(_iq22 A); +extern _iq21 _IQ21exp2(_iq21 A); +extern _iq20 _IQ20exp2(_iq20 A); +extern _iq19 _IQ19exp2(_iq19 A); +extern _iq18 _IQ18exp2(_iq18 A); +extern _iq17 _IQ17exp2(_iq17 A); +extern _iq16 _IQ16exp2(_iq16 A); +extern _iq15 _IQ15exp2(_iq15 A); +extern _iq14 _IQ14exp2(_iq14 A); +extern _iq13 _IQ13exp2(_iq13 A); +extern _iq12 _IQ12exp2(_iq12 A); +extern _iq11 _IQ11exp2(_iq11 A); +extern _iq10 _IQ10exp2(_iq10 A); +extern _iq9 _IQ9exp2(_iq9 A); +extern _iq8 _IQ8exp2(_iq8 A); +extern _iq7 _IQ7exp2(_iq7 A); +extern _iq6 _IQ6exp2(_iq6 A); +extern _iq5 _IQ5exp2(_iq5 A); +extern _iq4 _IQ4exp2(_iq4 A); +extern _iq3 _IQ3exp2(_iq3 A); +extern _iq2 _IQ2exp2(_iq2 A); +extern _iq1 _IQ1exp2(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQexp2(A) _IQ30exp2(A) +#endif +#if GLOBAL_Q == 29 +#define _IQexp2(A) _IQ29exp2(A) +#endif +#if GLOBAL_Q == 28 +#define _IQexp2(A) _IQ28exp2(A) +#endif +#if GLOBAL_Q == 27 +#define _IQexp2(A) _IQ27exp2(A) +#endif +#if GLOBAL_Q == 26 +#define _IQexp2(A) _IQ26exp2(A) +#endif +#if GLOBAL_Q == 25 +#define _IQexp2(A) _IQ25exp2(A) +#endif +#if GLOBAL_Q == 24 +#define _IQexp2(A) _IQ24exp2(A) +#endif +#if GLOBAL_Q == 23 +#define _IQexp2(A) _IQ23exp2(A) +#endif +#if GLOBAL_Q == 22 +#define _IQexp2(A) _IQ22exp2(A) +#endif +#if GLOBAL_Q == 21 +#define _IQexp2(A) _IQ21exp2(A) +#endif +#if GLOBAL_Q == 20 +#define _IQexp2(A) _IQ20exp2(A) +#endif +#if GLOBAL_Q == 19 +#define _IQexp2(A) _IQ19exp2(A) +#endif +#if GLOBAL_Q == 18 +#define _IQexp2(A) _IQ18exp2(A) +#endif +#if GLOBAL_Q == 17 +#define _IQexp2(A) _IQ17exp2(A) +#endif +#if GLOBAL_Q == 16 +#define _IQexp2(A) _IQ16exp2(A) +#endif +#if GLOBAL_Q == 15 +#define _IQexp2(A) _IQ15exp2(A) +#endif +#if GLOBAL_Q == 14 +#define _IQexp2(A) _IQ14exp2(A) +#endif +#if GLOBAL_Q == 13 +#define _IQexp2(A) _IQ13exp2(A) +#endif +#if GLOBAL_Q == 12 +#define _IQexp2(A) _IQ12exp2(A) +#endif +#if GLOBAL_Q == 11 +#define _IQexp2(A) _IQ11exp2(A) +#endif +#if GLOBAL_Q == 10 +#define _IQexp2(A) _IQ10exp2(A) +#endif +#if GLOBAL_Q == 9 +#define _IQexp2(A) _IQ9exp2(A) +#endif +#if GLOBAL_Q == 8 +#define _IQexp2(A) _IQ8exp2(A) +#endif +#if GLOBAL_Q == 7 +#define _IQexp2(A) _IQ7exp2(A) +#endif +#if GLOBAL_Q == 6 +#define _IQexp2(A) _IQ6exp2(A) +#endif +#if GLOBAL_Q == 5 +#define _IQexp2(A) _IQ5exp2(A) +#endif +#if GLOBAL_Q == 4 +#define _IQexp2(A) _IQ4exp2(A) +#endif +#if GLOBAL_Q == 3 +#define _IQexp2(A) _IQ3exp2(A) +#endif +#if GLOBAL_Q == 2 +#define _IQexp2(A) _IQ2exp2(A) +#endif +#if GLOBAL_Q == 1 +#define _IQexp2(A) _IQ1exp2(A) +#endif + +//***************************************************************************** +// +// Returns the integer portion of an IQ number. +// +//***************************************************************************** +#define _IQ30int(A) ((A) >> 30) +#define _IQ29int(A) ((A) >> 29) +#define _IQ28int(A) ((A) >> 28) +#define _IQ27int(A) ((A) >> 27) +#define _IQ26int(A) ((A) >> 26) +#define _IQ25int(A) ((A) >> 25) +#define _IQ24int(A) ((A) >> 24) +#define _IQ23int(A) ((A) >> 23) +#define _IQ22int(A) ((A) >> 22) +#define _IQ21int(A) ((A) >> 21) +#define _IQ20int(A) ((A) >> 20) +#define _IQ19int(A) ((A) >> 19) +#define _IQ18int(A) ((A) >> 18) +#define _IQ17int(A) ((A) >> 17) +#define _IQ16int(A) ((A) >> 16) +#define _IQ15int(A) ((A) >> 15) +#define _IQ14int(A) ((A) >> 14) +#define _IQ13int(A) ((A) >> 13) +#define _IQ12int(A) ((A) >> 12) +#define _IQ11int(A) ((A) >> 11) +#define _IQ10int(A) ((A) >> 10) +#define _IQ9int(A) ((A) >> 9) +#define _IQ8int(A) ((A) >> 8) +#define _IQ7int(A) ((A) >> 7) +#define _IQ6int(A) ((A) >> 6) +#define _IQ5int(A) ((A) >> 5) +#define _IQ4int(A) ((A) >> 4) +#define _IQ3int(A) ((A) >> 3) +#define _IQ2int(A) ((A) >> 2) +#define _IQ1int(A) ((A) >> 1) +#define _IQint(A) ((A) >> GLOBAL_Q) + +//***************************************************************************** +// +// Computes the fractional portion of an IQ number. +// +//***************************************************************************** +extern _iq30 _IQ30frac(_iq30 A); +extern _iq29 _IQ29frac(_iq29 A); +extern _iq28 _IQ28frac(_iq28 A); +extern _iq27 _IQ27frac(_iq27 A); +extern _iq26 _IQ26frac(_iq26 A); +extern _iq25 _IQ25frac(_iq25 A); +extern _iq24 _IQ24frac(_iq24 A); +extern _iq23 _IQ23frac(_iq23 A); +extern _iq22 _IQ22frac(_iq22 A); +extern _iq21 _IQ21frac(_iq21 A); +extern _iq20 _IQ20frac(_iq20 A); +extern _iq19 _IQ19frac(_iq19 A); +extern _iq18 _IQ18frac(_iq18 A); +extern _iq17 _IQ17frac(_iq17 A); +extern _iq16 _IQ16frac(_iq16 A); +extern _iq15 _IQ15frac(_iq15 A); +extern _iq14 _IQ14frac(_iq14 A); +extern _iq13 _IQ13frac(_iq13 A); +extern _iq12 _IQ12frac(_iq12 A); +extern _iq11 _IQ11frac(_iq11 A); +extern _iq10 _IQ10frac(_iq10 A); +extern _iq9 _IQ9frac(_iq9 A); +extern _iq8 _IQ8frac(_iq8 A); +extern _iq7 _IQ7frac(_iq7 A); +extern _iq6 _IQ6frac(_iq6 A); +extern _iq5 _IQ5frac(_iq5 A); +extern _iq4 _IQ4frac(_iq4 A); +extern _iq3 _IQ3frac(_iq3 A); +extern _iq2 _IQ2frac(_iq2 A); +extern _iq1 _IQ1frac(_iq1 A); + +#if GLOBAL_Q == 30 +#define _IQfrac(A) _IQ30frac(A) +#endif +#if GLOBAL_Q == 29 +#define _IQfrac(A) _IQ29frac(A) +#endif +#if GLOBAL_Q == 28 +#define _IQfrac(A) _IQ28frac(A) +#endif +#if GLOBAL_Q == 27 +#define _IQfrac(A) _IQ27frac(A) +#endif +#if GLOBAL_Q == 26 +#define _IQfrac(A) _IQ26frac(A) +#endif +#if GLOBAL_Q == 25 +#define _IQfrac(A) _IQ25frac(A) +#endif +#if GLOBAL_Q == 24 +#define _IQfrac(A) _IQ24frac(A) +#endif +#if GLOBAL_Q == 23 +#define _IQfrac(A) _IQ23frac(A) +#endif +#if GLOBAL_Q == 22 +#define _IQfrac(A) _IQ22frac(A) +#endif +#if GLOBAL_Q == 21 +#define _IQfrac(A) _IQ21frac(A) +#endif +#if GLOBAL_Q == 20 +#define _IQfrac(A) _IQ20frac(A) +#endif +#if GLOBAL_Q == 19 +#define _IQfrac(A) _IQ19frac(A) +#endif +#if GLOBAL_Q == 18 +#define _IQfrac(A) _IQ18frac(A) +#endif +#if GLOBAL_Q == 17 +#define _IQfrac(A) _IQ17frac(A) +#endif +#if GLOBAL_Q == 16 +#define _IQfrac(A) _IQ16frac(A) +#endif +#if GLOBAL_Q == 15 +#define _IQfrac(A) _IQ15frac(A) +#endif +#if GLOBAL_Q == 14 +#define _IQfrac(A) _IQ14frac(A) +#endif +#if GLOBAL_Q == 13 +#define _IQfrac(A) _IQ13frac(A) +#endif +#if GLOBAL_Q == 12 +#define _IQfrac(A) _IQ12frac(A) +#endif +#if GLOBAL_Q == 11 +#define _IQfrac(A) _IQ11frac(A) +#endif +#if GLOBAL_Q == 10 +#define _IQfrac(A) _IQ10frac(A) +#endif +#if GLOBAL_Q == 9 +#define _IQfrac(A) _IQ9frac(A) +#endif +#if GLOBAL_Q == 8 +#define _IQfrac(A) _IQ8frac(A) +#endif +#if GLOBAL_Q == 7 +#define _IQfrac(A) _IQ7frac(A) +#endif +#if GLOBAL_Q == 6 +#define _IQfrac(A) _IQ6frac(A) +#endif +#if GLOBAL_Q == 5 +#define _IQfrac(A) _IQ5frac(A) +#endif +#if GLOBAL_Q == 4 +#define _IQfrac(A) _IQ4frac(A) +#endif +#if GLOBAL_Q == 3 +#define _IQfrac(A) _IQ3frac(A) +#endif +#if GLOBAL_Q == 2 +#define _IQfrac(A) _IQ2frac(A) +#endif +#if GLOBAL_Q == 1 +#define _IQfrac(A) _IQ1frac(A) +#endif + +//***************************************************************************** +// +// Multiplies two IQ numbers in the specified iQ formats, returning the result +// in another IQ format. +// +//***************************************************************************** +extern long __IQxmpy(long A, long B, long S); +#define _IQ30mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 30 + 32 - (IQA) - (IQB)) +#define _IQ29mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 29 + 32 - (IQA) - (IQB)) +#define _IQ28mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 28 + 32 - (IQA) - (IQB)) +#define _IQ27mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 27 + 32 - (IQA) - (IQB)) +#define _IQ26mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 26 + 32 - (IQA) - (IQB)) +#define _IQ25mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 25 + 32 - (IQA) - (IQB)) +#define _IQ24mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 24 + 32 - (IQA) - (IQB)) +#define _IQ23mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 23 + 32 - (IQA) - (IQB)) +#define _IQ22mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 22 + 32 - (IQA) - (IQB)) +#define _IQ21mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 21 + 32 - (IQA) - (IQB)) +#define _IQ20mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 20 + 32 - (IQA) - (IQB)) +#define _IQ19mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 19 + 32 - (IQA) - (IQB)) +#define _IQ18mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 18 + 32 - (IQA) - (IQB)) +#define _IQ17mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 17 + 32 - (IQA) - (IQB)) +#define _IQ16mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 16 + 32 - (IQA) - (IQB)) +#define _IQ15mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 15 + 32 - (IQA) - (IQB)) +#define _IQ14mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 14 + 32 - (IQA) - (IQB)) +#define _IQ13mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 13 + 32 - (IQA) - (IQB)) +#define _IQ12mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 12 + 32 - (IQA) - (IQB)) +#define _IQ11mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 11 + 32 - (IQA) - (IQB)) +#define _IQ10mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 10 + 32 - (IQA) - (IQB)) +#define _IQ9mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 9 + 32 - (IQA) - (IQB)) +#define _IQ8mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 8 + 32 - (IQA) - (IQB)) +#define _IQ7mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 7 + 32 - (IQA) - (IQB)) +#define _IQ6mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 6 + 32 - (IQA) - (IQB)) +#define _IQ5mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 5 + 32 - (IQA) - (IQB)) +#define _IQ4mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 4 + 32 - (IQA) - (IQB)) +#define _IQ3mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 3 + 32 - (IQA) - (IQB)) +#define _IQ2mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 2 + 32 - (IQA) - (IQB)) +#define _IQ1mpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, 1 + 32 - (IQA) - (IQB)) +#define _IQmpyIQX(A, IQA, B, IQB) __IQxmpy(A, B, \ + (GLOBAL_Q) + 32 - (IQA) - (IQB)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer. +// +//***************************************************************************** +#define _IQ30mpyI32(A, B) ((A) * (B)) +#define _IQ29mpyI32(A, B) ((A) * (B)) +#define _IQ28mpyI32(A, B) ((A) * (B)) +#define _IQ27mpyI32(A, B) ((A) * (B)) +#define _IQ26mpyI32(A, B) ((A) * (B)) +#define _IQ25mpyI32(A, B) ((A) * (B)) +#define _IQ24mpyI32(A, B) ((A) * (B)) +#define _IQ23mpyI32(A, B) ((A) * (B)) +#define _IQ22mpyI32(A, B) ((A) * (B)) +#define _IQ21mpyI32(A, B) ((A) * (B)) +#define _IQ20mpyI32(A, B) ((A) * (B)) +#define _IQ19mpyI32(A, B) ((A) * (B)) +#define _IQ18mpyI32(A, B) ((A) * (B)) +#define _IQ17mpyI32(A, B) ((A) * (B)) +#define _IQ16mpyI32(A, B) ((A) * (B)) +#define _IQ15mpyI32(A, B) ((A) * (B)) +#define _IQ14mpyI32(A, B) ((A) * (B)) +#define _IQ13mpyI32(A, B) ((A) * (B)) +#define _IQ12mpyI32(A, B) ((A) * (B)) +#define _IQ11mpyI32(A, B) ((A) * (B)) +#define _IQ10mpyI32(A, B) ((A) * (B)) +#define _IQ9mpyI32(A, B) ((A) * (B)) +#define _IQ8mpyI32(A, B) ((A) * (B)) +#define _IQ7mpyI32(A, B) ((A) * (B)) +#define _IQ6mpyI32(A, B) ((A) * (B)) +#define _IQ5mpyI32(A, B) ((A) * (B)) +#define _IQ4mpyI32(A, B) ((A) * (B)) +#define _IQ3mpyI32(A, B) ((A) * (B)) +#define _IQ2mpyI32(A, B) ((A) * (B)) +#define _IQ1mpyI32(A, B) ((A) * (B)) +#define _IQmpyI32(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the integer portion. +// +//***************************************************************************** +extern _iq30 _IQ30mpyI32int(_iq30 A, long B); +extern _iq29 _IQ29mpyI32int(_iq29 A, long B); +extern _iq28 _IQ28mpyI32int(_iq28 A, long B); +extern _iq27 _IQ27mpyI32int(_iq27 A, long B); +extern _iq26 _IQ26mpyI32int(_iq26 A, long B); +extern _iq25 _IQ25mpyI32int(_iq25 A, long B); +extern _iq24 _IQ24mpyI32int(_iq24 A, long B); +extern _iq23 _IQ23mpyI32int(_iq23 A, long B); +extern _iq22 _IQ22mpyI32int(_iq22 A, long B); +extern _iq21 _IQ21mpyI32int(_iq21 A, long B); +extern _iq20 _IQ20mpyI32int(_iq20 A, long B); +extern _iq19 _IQ19mpyI32int(_iq19 A, long B); +extern _iq18 _IQ18mpyI32int(_iq18 A, long B); +extern _iq17 _IQ17mpyI32int(_iq17 A, long B); +extern _iq16 _IQ16mpyI32int(_iq16 A, long B); +extern _iq15 _IQ15mpyI32int(_iq15 A, long B); +extern _iq14 _IQ14mpyI32int(_iq14 A, long B); +extern _iq13 _IQ13mpyI32int(_iq13 A, long B); +extern _iq12 _IQ12mpyI32int(_iq12 A, long B); +extern _iq11 _IQ11mpyI32int(_iq11 A, long B); +extern _iq10 _IQ10mpyI32int(_iq10 A, long B); +extern _iq9 _IQ9mpyI32int(_iq9 A, long B); +extern _iq8 _IQ8mpyI32int(_iq8 A, long B); +extern _iq7 _IQ7mpyI32int(_iq7 A, long B); +extern _iq6 _IQ6mpyI32int(_iq6 A, long B); +extern _iq5 _IQ5mpyI32int(_iq5 A, long B); +extern _iq4 _IQ4mpyI32int(_iq4 A, long B); +extern _iq3 _IQ3mpyI32int(_iq3 A, long B); +extern _iq2 _IQ2mpyI32int(_iq2 A, long B); +extern _iq1 _IQ1mpyI32int(_iq1 A, long B); + +#if GLOBAL_Q == 30 +#define _IQmpyI32int(A, B) _IQ30mpyI32int(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQmpyI32int(A, B) _IQ29mpyI32int(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQmpyI32int(A, B) _IQ28mpyI32int(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQmpyI32int(A, B) _IQ27mpyI32int(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQmpyI32int(A, B) _IQ26mpyI32int(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQmpyI32int(A, B) _IQ25mpyI32int(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQmpyI32int(A, B) _IQ24mpyI32int(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQmpyI32int(A, B) _IQ23mpyI32int(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQmpyI32int(A, B) _IQ22mpyI32int(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQmpyI32int(A, B) _IQ21mpyI32int(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQmpyI32int(A, B) _IQ20mpyI32int(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQmpyI32int(A, B) _IQ19mpyI32int(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQmpyI32int(A, B) _IQ18mpyI32int(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQmpyI32int(A, B) _IQ17mpyI32int(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQmpyI32int(A, B) _IQ16mpyI32int(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQmpyI32int(A, B) _IQ15mpyI32int(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQmpyI32int(A, B) _IQ14mpyI32int(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQmpyI32int(A, B) _IQ13mpyI32int(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQmpyI32int(A, B) _IQ12mpyI32int(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQmpyI32int(A, B) _IQ11mpyI32int(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQmpyI32int(A, B) _IQ10mpyI32int(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQmpyI32int(A, B) _IQ9mpyI32int(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQmpyI32int(A, B) _IQ8mpyI32int(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQmpyI32int(A, B) _IQ7mpyI32int(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQmpyI32int(A, B) _IQ6mpyI32int(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQmpyI32int(A, B) _IQ5mpyI32int(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQmpyI32int(A, B) _IQ4mpyI32int(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQmpyI32int(A, B) _IQ3mpyI32int(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQmpyI32int(A, B) _IQ2mpyI32int(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQmpyI32int(A, B) _IQ1mpyI32int(A, B) +#endif + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the fractional portion. +// +//***************************************************************************** +extern _iq30 _IQ30mpyI32frac(_iq30 A, long B); +extern _iq29 _IQ29mpyI32frac(_iq29 A, long B); +extern _iq28 _IQ28mpyI32frac(_iq28 A, long B); +extern _iq27 _IQ27mpyI32frac(_iq27 A, long B); +extern _iq26 _IQ26mpyI32frac(_iq26 A, long B); +extern _iq25 _IQ25mpyI32frac(_iq25 A, long B); +extern _iq24 _IQ24mpyI32frac(_iq24 A, long B); +extern _iq23 _IQ23mpyI32frac(_iq23 A, long B); +extern _iq22 _IQ22mpyI32frac(_iq22 A, long B); +extern _iq21 _IQ21mpyI32frac(_iq21 A, long B); +extern _iq20 _IQ20mpyI32frac(_iq20 A, long B); +extern _iq19 _IQ19mpyI32frac(_iq19 A, long B); +extern _iq18 _IQ18mpyI32frac(_iq18 A, long B); +extern _iq17 _IQ17mpyI32frac(_iq17 A, long B); +extern _iq16 _IQ16mpyI32frac(_iq16 A, long B); +extern _iq15 _IQ15mpyI32frac(_iq15 A, long B); +extern _iq14 _IQ14mpyI32frac(_iq14 A, long B); +extern _iq13 _IQ13mpyI32frac(_iq13 A, long B); +extern _iq12 _IQ12mpyI32frac(_iq12 A, long B); +extern _iq11 _IQ11mpyI32frac(_iq11 A, long B); +extern _iq10 _IQ10mpyI32frac(_iq10 A, long B); +extern _iq9 _IQ9mpyI32frac(_iq9 A, long B); +extern _iq8 _IQ8mpyI32frac(_iq8 A, long B); +extern _iq7 _IQ7mpyI32frac(_iq7 A, long B); +extern _iq6 _IQ6mpyI32frac(_iq6 A, long B); +extern _iq5 _IQ5mpyI32frac(_iq5 A, long B); +extern _iq4 _IQ4mpyI32frac(_iq4 A, long B); +extern _iq3 _IQ3mpyI32frac(_iq3 A, long B); +extern _iq2 _IQ2mpyI32frac(_iq2 A, long B); +extern _iq1 _IQ1mpyI32frac(_iq1 A, long B); + +#if GLOBAL_Q == 30 +#define _IQmpyI32frac(A, B) _IQ30mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQmpyI32frac(A, B) _IQ29mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQmpyI32frac(A, B) _IQ28mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQmpyI32frac(A, B) _IQ27mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQmpyI32frac(A, B) _IQ26mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQmpyI32frac(A, B) _IQ25mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQmpyI32frac(A, B) _IQ24mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQmpyI32frac(A, B) _IQ23mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQmpyI32frac(A, B) _IQ22mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQmpyI32frac(A, B) _IQ21mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQmpyI32frac(A, B) _IQ20mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQmpyI32frac(A, B) _IQ19mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQmpyI32frac(A, B) _IQ18mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQmpyI32frac(A, B) _IQ17mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQmpyI32frac(A, B) _IQ16mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQmpyI32frac(A, B) _IQ15mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQmpyI32frac(A, B) _IQ14mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQmpyI32frac(A, B) _IQ13mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQmpyI32frac(A, B) _IQ12mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQmpyI32frac(A, B) _IQ11mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQmpyI32frac(A, B) _IQ10mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQmpyI32frac(A, B) _IQ9mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQmpyI32frac(A, B) _IQ8mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQmpyI32frac(A, B) _IQ7mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQmpyI32frac(A, B) _IQ6mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQmpyI32frac(A, B) _IQ5mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQmpyI32frac(A, B) _IQ4mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQmpyI32frac(A, B) _IQ3mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQmpyI32frac(A, B) _IQ2mpyI32frac(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQmpyI32frac(A, B) _IQ1mpyI32frac(A, B) +#endif + +//***************************************************************************** +// +// Computes the square root of A^2 + B^2 using IQ numbers. +// +//***************************************************************************** +extern _iq30 _IQ30mag(_iq30 A, _iq30 B); +extern _iq29 _IQ29mag(_iq29 A, _iq29 B); +extern _iq28 _IQ28mag(_iq28 A, _iq28 B); +extern _iq27 _IQ27mag(_iq27 A, _iq27 B); +extern _iq26 _IQ26mag(_iq26 A, _iq26 B); +extern _iq25 _IQ25mag(_iq25 A, _iq25 B); +extern _iq24 _IQ24mag(_iq24 A, _iq24 B); +extern _iq23 _IQ23mag(_iq23 A, _iq23 B); +extern _iq22 _IQ22mag(_iq22 A, _iq22 B); +extern _iq21 _IQ21mag(_iq21 A, _iq21 B); +extern _iq20 _IQ20mag(_iq20 A, _iq20 B); +extern _iq19 _IQ19mag(_iq19 A, _iq19 B); +extern _iq18 _IQ18mag(_iq18 A, _iq18 B); +extern _iq17 _IQ17mag(_iq17 A, _iq17 B); +extern _iq16 _IQ16mag(_iq16 A, _iq16 B); +extern _iq15 _IQ15mag(_iq15 A, _iq15 B); +extern _iq14 _IQ14mag(_iq14 A, _iq14 B); +extern _iq13 _IQ13mag(_iq13 A, _iq13 B); +extern _iq12 _IQ12mag(_iq12 A, _iq12 B); +extern _iq11 _IQ11mag(_iq11 A, _iq11 B); +extern _iq10 _IQ10mag(_iq10 A, _iq10 B); +extern _iq9 _IQ9mag(_iq9 A, _iq9 B); +extern _iq8 _IQ8mag(_iq8 A, _iq8 B); +extern _iq7 _IQ7mag(_iq7 A, _iq7 B); +extern _iq6 _IQ6mag(_iq6 A, _iq6 B); +extern _iq5 _IQ5mag(_iq5 A, _iq5 B); +extern _iq4 _IQ4mag(_iq4 A, _iq4 B); +extern _iq3 _IQ3mag(_iq3 A, _iq3 B); +extern _iq2 _IQ2mag(_iq2 A, _iq2 B); +extern _iq1 _IQ1mag(_iq1 A, _iq1 B); + +#if GLOBAL_Q == 30 +#define _IQmag(A, B) _IQ30mag(A, B) +#endif +#if GLOBAL_Q == 29 +#define _IQmag(A, B) _IQ29mag(A, B) +#endif +#if GLOBAL_Q == 28 +#define _IQmag(A, B) _IQ28mag(A, B) +#endif +#if GLOBAL_Q == 27 +#define _IQmag(A, B) _IQ27mag(A, B) +#endif +#if GLOBAL_Q == 26 +#define _IQmag(A, B) _IQ26mag(A, B) +#endif +#if GLOBAL_Q == 25 +#define _IQmag(A, B) _IQ25mag(A, B) +#endif +#if GLOBAL_Q == 24 +#define _IQmag(A, B) _IQ24mag(A, B) +#endif +#if GLOBAL_Q == 23 +#define _IQmag(A, B) _IQ23mag(A, B) +#endif +#if GLOBAL_Q == 22 +#define _IQmag(A, B) _IQ22mag(A, B) +#endif +#if GLOBAL_Q == 21 +#define _IQmag(A, B) _IQ21mag(A, B) +#endif +#if GLOBAL_Q == 20 +#define _IQmag(A, B) _IQ20mag(A, B) +#endif +#if GLOBAL_Q == 19 +#define _IQmag(A, B) _IQ19mag(A, B) +#endif +#if GLOBAL_Q == 18 +#define _IQmag(A, B) _IQ18mag(A, B) +#endif +#if GLOBAL_Q == 17 +#define _IQmag(A, B) _IQ17mag(A, B) +#endif +#if GLOBAL_Q == 16 +#define _IQmag(A, B) _IQ16mag(A, B) +#endif +#if GLOBAL_Q == 15 +#define _IQmag(A, B) _IQ15mag(A, B) +#endif +#if GLOBAL_Q == 14 +#define _IQmag(A, B) _IQ14mag(A, B) +#endif +#if GLOBAL_Q == 13 +#define _IQmag(A, B) _IQ13mag(A, B) +#endif +#if GLOBAL_Q == 12 +#define _IQmag(A, B) _IQ12mag(A, B) +#endif +#if GLOBAL_Q == 11 +#define _IQmag(A, B) _IQ11mag(A, B) +#endif +#if GLOBAL_Q == 10 +#define _IQmag(A, B) _IQ10mag(A, B) +#endif +#if GLOBAL_Q == 9 +#define _IQmag(A, B) _IQ9mag(A, B) +#endif +#if GLOBAL_Q == 8 +#define _IQmag(A, B) _IQ8mag(A, B) +#endif +#if GLOBAL_Q == 7 +#define _IQmag(A, B) _IQ7mag(A, B) +#endif +#if GLOBAL_Q == 6 +#define _IQmag(A, B) _IQ6mag(A, B) +#endif +#if GLOBAL_Q == 5 +#define _IQmag(A, B) _IQ5mag(A, B) +#endif +#if GLOBAL_Q == 4 +#define _IQmag(A, B) _IQ4mag(A, B) +#endif +#if GLOBAL_Q == 3 +#define _IQmag(A, B) _IQ3mag(A, B) +#endif +#if GLOBAL_Q == 2 +#define _IQmag(A, B) _IQ2mag(A, B) +#endif +#if GLOBAL_Q == 1 +#define _IQmag(A, B) _IQ1mag(A, B) +#endif + +//***************************************************************************** +// +// Converts a string into an IQ number. +// +//***************************************************************************** +extern _iq _atoIQN(const char *A, long B); +#define _atoIQ30(A) _atoIQN(A, 30) +#define _atoIQ29(A) _atoIQN(A, 29) +#define _atoIQ28(A) _atoIQN(A, 28) +#define _atoIQ27(A) _atoIQN(A, 27) +#define _atoIQ26(A) _atoIQN(A, 26) +#define _atoIQ25(A) _atoIQN(A, 25) +#define _atoIQ24(A) _atoIQN(A, 24) +#define _atoIQ23(A) _atoIQN(A, 23) +#define _atoIQ22(A) _atoIQN(A, 22) +#define _atoIQ21(A) _atoIQN(A, 21) +#define _atoIQ20(A) _atoIQN(A, 20) +#define _atoIQ19(A) _atoIQN(A, 19) +#define _atoIQ18(A) _atoIQN(A, 18) +#define _atoIQ17(A) _atoIQN(A, 17) +#define _atoIQ16(A) _atoIQN(A, 16) +#define _atoIQ15(A) _atoIQN(A, 15) +#define _atoIQ14(A) _atoIQN(A, 14) +#define _atoIQ13(A) _atoIQN(A, 13) +#define _atoIQ12(A) _atoIQN(A, 12) +#define _atoIQ11(A) _atoIQN(A, 11) +#define _atoIQ10(A) _atoIQN(A, 10) +#define _atoIQ9(A) _atoIQN(A, 9) +#define _atoIQ8(A) _atoIQN(A, 8) +#define _atoIQ7(A) _atoIQN(A, 7) +#define _atoIQ6(A) _atoIQN(A, 6) +#define _atoIQ5(A) _atoIQN(A, 5) +#define _atoIQ4(A) _atoIQN(A, 4) +#define _atoIQ3(A) _atoIQN(A, 3) +#define _atoIQ2(A) _atoIQN(A, 2) +#define _atoIQ1(A) _atoIQN(A, 1) +#define _atoIQ(A) _atoIQN(A, GLOBAL_Q) + +//***************************************************************************** +// +// Converts an IQ number into a string. +// +//***************************************************************************** +extern int __IQNtoa(char *A, const char *B, _iq C, int D); +#define _IQ30toa(A, B, C) __IQNtoa(A, B, C, 30); +#define _IQ29toa(A, B, C) __IQNtoa(A, B, C, 29); +#define _IQ28toa(A, B, C) __IQNtoa(A, B, C, 28); +#define _IQ27toa(A, B, C) __IQNtoa(A, B, C, 27); +#define _IQ26toa(A, B, C) __IQNtoa(A, B, C, 26); +#define _IQ25toa(A, B, C) __IQNtoa(A, B, C, 25); +#define _IQ24toa(A, B, C) __IQNtoa(A, B, C, 24); +#define _IQ23toa(A, B, C) __IQNtoa(A, B, C, 23); +#define _IQ22toa(A, B, C) __IQNtoa(A, B, C, 22); +#define _IQ21toa(A, B, C) __IQNtoa(A, B, C, 21); +#define _IQ20toa(A, B, C) __IQNtoa(A, B, C, 20); +#define _IQ19toa(A, B, C) __IQNtoa(A, B, C, 19); +#define _IQ18toa(A, B, C) __IQNtoa(A, B, C, 18); +#define _IQ17toa(A, B, C) __IQNtoa(A, B, C, 17); +#define _IQ16toa(A, B, C) __IQNtoa(A, B, C, 16); +#define _IQ15toa(A, B, C) __IQNtoa(A, B, C, 15); +#define _IQ14toa(A, B, C) __IQNtoa(A, B, C, 14); +#define _IQ13toa(A, B, C) __IQNtoa(A, B, C, 13); +#define _IQ12toa(A, B, C) __IQNtoa(A, B, C, 12); +#define _IQ11toa(A, B, C) __IQNtoa(A, B, C, 11); +#define _IQ10toa(A, B, C) __IQNtoa(A, B, C, 10); +#define _IQ9toa(A, B, C) __IQNtoa(A, B, C, 9); +#define _IQ8toa(A, B, C) __IQNtoa(A, B, C, 8); +#define _IQ7toa(A, B, C) __IQNtoa(A, B, C, 7); +#define _IQ6toa(A, B, C) __IQNtoa(A, B, C, 6); +#define _IQ5toa(A, B, C) __IQNtoa(A, B, C, 5); +#define _IQ4toa(A, B, C) __IQNtoa(A, B, C, 4); +#define _IQ3toa(A, B, C) __IQNtoa(A, B, C, 3); +#define _IQ2toa(A, B, C) __IQNtoa(A, B, C, 2); +#define _IQ1toa(A, B, C) __IQNtoa(A, B, C, 1); +#define _IQtoa(A, B, C) __IQNtoa(A, B, C, GLOBAL_Q) + +//***************************************************************************** +// +// Computes the absolute value of an IQ number. +// +//***************************************************************************** +#define _IQ30abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ29abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ28abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ27abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ26abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ25abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ24abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ23abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ22abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ21abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ20abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ19abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ18abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ17abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ16abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ15abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ14abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ13abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ12abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ11abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ10abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ9abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ8abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ7abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ6abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ5abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ4abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ3abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ2abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQ1abs(A) (((A) < 0) ? - (A) : (A)) +#define _IQabs(A) (((A) < 0) ? - (A) : (A)) + +//***************************************************************************** +// +// Otherwise, floating point math is being used. +// +//***************************************************************************** +#else // MATH_TYPE == FLOAT_MATH + +//***************************************************************************** +// +// The floating point equivalent of the various IQ formats. +// +//***************************************************************************** +typedef float _iq30; +typedef float _iq29; +typedef float _iq28; +typedef float _iq27; +typedef float _iq26; +typedef float _iq25; +typedef float _iq24; +typedef float _iq23; +typedef float _iq22; +typedef float _iq21; +typedef float _iq20; +typedef float _iq19; +typedef float _iq18; +typedef float _iq17; +typedef float _iq16; +typedef float _iq15; +typedef float _iq14; +typedef float _iq13; +typedef float _iq12; +typedef float _iq11; +typedef float _iq10; +typedef float _iq9; +typedef float _iq8; +typedef float _iq7; +typedef float _iq6; +typedef float _iq5; +typedef float _iq4; +typedef float _iq3; +typedef float _iq2; +typedef float _iq1; +typedef float _iq; + +//***************************************************************************** +// +// Simple multiplies or divides. +// +//***************************************************************************** +#define _IQmpy2(A) ((A) * 2.0) +#define _IQmpy4(A) ((A) * 4.0) +#define _IQmpy8(A) ((A) * 8.0) +#define _IQmpy16(A) ((A) * 16.0) +#define _IQmpy32(A) ((A) * 32.0) +#define _IQmpy64(A) ((A) * 64.0) +#define _IQdiv2(A) ((A) / 2.0) +#define _IQdiv4(A) ((A) / 4.0) +#define _IQdiv8(A) ((A) / 8.0) +#define _IQdiv16(A) ((A) / 16.0) +#define _IQdiv32(A) ((A) / 32.0) +#define _IQdiv64(A) ((A) / 64.0) + +//***************************************************************************** +// +// Convert a value into an IQ number. +// +//***************************************************************************** +#define _IQ30(A) (A) +#define _IQ29(A) (A) +#define _IQ28(A) (A) +#define _IQ27(A) (A) +#define _IQ26(A) (A) +#define _IQ25(A) (A) +#define _IQ24(A) (A) +#define _IQ23(A) (A) +#define _IQ22(A) (A) +#define _IQ21(A) (A) +#define _IQ20(A) (A) +#define _IQ19(A) (A) +#define _IQ18(A) (A) +#define _IQ17(A) (A) +#define _IQ16(A) (A) +#define _IQ15(A) (A) +#define _IQ14(A) (A) +#define _IQ13(A) (A) +#define _IQ12(A) (A) +#define _IQ11(A) (A) +#define _IQ10(A) (A) +#define _IQ9(A) (A) +#define _IQ8(A) (A) +#define _IQ7(A) (A) +#define _IQ6(A) (A) +#define _IQ5(A) (A) +#define _IQ4(A) (A) +#define _IQ3(A) (A) +#define _IQ2(A) (A) +#define _IQ1(A) (A) +#define _IQ(A) (A) + +//***************************************************************************** +// +// Convert an IQ number to a floating point value. +// +//***************************************************************************** +#define _IQ30toF(A) (A) +#define _IQ29toF(A) (A) +#define _IQ28toF(A) (A) +#define _IQ27toF(A) (A) +#define _IQ26toF(A) (A) +#define _IQ25toF(A) (A) +#define _IQ24toF(A) (A) +#define _IQ23toF(A) (A) +#define _IQ22toF(A) (A) +#define _IQ21toF(A) (A) +#define _IQ20toF(A) (A) +#define _IQ19toF(A) (A) +#define _IQ18toF(A) (A) +#define _IQ17toF(A) (A) +#define _IQ16toF(A) (A) +#define _IQ15toF(A) (A) +#define _IQ14toF(A) (A) +#define _IQ13toF(A) (A) +#define _IQ12toF(A) (A) +#define _IQ11toF(A) (A) +#define _IQ10toF(A) (A) +#define _IQ9toF(A) (A) +#define _IQ8toF(A) (A) +#define _IQ7toF(A) (A) +#define _IQ6toF(A) (A) +#define _IQ5toF(A) (A) +#define _IQ4toF(A) (A) +#define _IQ3toF(A) (A) +#define _IQ2toF(A) (A) +#define _IQ1toF(A) (A) +#define _IQtoF(A) (A) + +//***************************************************************************** +// +// Convert an IQ number to a double-precision floating point value. +// +//***************************************************************************** +#define _IQ30toD(A) (A) +#define _IQ29toD(A) (A) +#define _IQ28toD(A) (A) +#define _IQ27toD(A) (A) +#define _IQ26toD(A) (A) +#define _IQ25toD(A) (A) +#define _IQ24toD(A) (A) +#define _IQ23toD(A) (A) +#define _IQ22toD(A) (A) +#define _IQ21toD(A) (A) +#define _IQ20toD(A) (A) +#define _IQ19toD(A) (A) +#define _IQ18toD(A) (A) +#define _IQ17toD(A) (A) +#define _IQ16toD(A) (A) +#define _IQ15toD(A) (A) +#define _IQ14toD(A) (A) +#define _IQ13toD(A) (A) +#define _IQ12toD(A) (A) +#define _IQ11toD(A) (A) +#define _IQ10toD(A) (A) +#define _IQ9toD(A) (A) +#define _IQ8toD(A) (A) +#define _IQ7toD(A) (A) +#define _IQ6toD(A) (A) +#define _IQ5toD(A) (A) +#define _IQ4toD(A) (A) +#define _IQ3toD(A) (A) +#define _IQ2toD(A) (A) +#define _IQ1toD(A) (A) +#define _IQtoD(A) (A) + +//***************************************************************************** +// +// Saturates an IQ number in a given range. +// +//***************************************************************************** +#define _IQsat(A, Pos, Neg) (((A) > (Pos)) ? \ + (Pos) : \ + (((A) < (Neg)) ? (Neg) : (A))) + +//***************************************************************************** +// +// Converts an IQ number between the global IQ format and a specified IQ +// format. +// +//***************************************************************************** +#define _IQtoIQ30(A) (A) +#define _IQ30toIQ(A) (A) +#define _IQtoIQ29(A) (A) +#define _IQ29toIQ(A) (A) +#define _IQtoIQ28(A) (A) +#define _IQ28toIQ(A) (A) +#define _IQtoIQ27(A) (A) +#define _IQ27toIQ(A) (A) +#define _IQtoIQ26(A) (A) +#define _IQ26toIQ(A) (A) +#define _IQtoIQ25(A) (A) +#define _IQ25toIQ(A) (A) +#define _IQtoIQ24(A) (A) +#define _IQ24toIQ(A) (A) +#define _IQtoIQ23(A) (A) +#define _IQ23toIQ(A) (A) +#define _IQtoIQ22(A) (A) +#define _IQ22toIQ(A) (A) +#define _IQtoIQ21(A) (A) +#define _IQ21toIQ(A) (A) +#define _IQtoIQ20(A) (A) +#define _IQ20toIQ(A) (A) +#define _IQtoIQ19(A) (A) +#define _IQ19toIQ(A) (A) +#define _IQtoIQ18(A) (A) +#define _IQ18toIQ(A) (A) +#define _IQtoIQ17(A) (A) +#define _IQ17toIQ(A) (A) +#define _IQtoIQ16(A) (A) +#define _IQ16toIQ(A) (A) +#define _IQtoIQ15(A) (A) +#define _IQ15toIQ(A) (A) +#define _IQtoIQ14(A) (A) +#define _IQ14toIQ(A) (A) +#define _IQtoIQ13(A) (A) +#define _IQ13toIQ(A) (A) +#define _IQtoIQ12(A) (A) +#define _IQ12toIQ(A) (A) +#define _IQtoIQ11(A) (A) +#define _IQ11toIQ(A) (A) +#define _IQtoIQ10(A) (A) +#define _IQ10toIQ(A) (A) +#define _IQtoIQ9(A) (A) +#define _IQ9toIQ(A) (A) +#define _IQtoIQ8(A) (A) +#define _IQ8toIQ(A) (A) +#define _IQtoIQ7(A) (A) +#define _IQ7toIQ(A) (A) +#define _IQtoIQ6(A) (A) +#define _IQ6toIQ(A) (A) +#define _IQtoIQ5(A) (A) +#define _IQ5toIQ(A) (A) +#define _IQtoIQ4(A) (A) +#define _IQ4toIQ(A) (A) +#define _IQtoIQ3(A) (A) +#define _IQ3toIQ(A) (A) +#define _IQtoIQ2(A) (A) +#define _IQ2toIQ(A) (A) +#define _IQtoIQ1(A) (A) +#define _IQ1toIQ(A) (A) + +//***************************************************************************** +// +// Converts a number between IQ format and 16-bit Qn format. +// +//***************************************************************************** +#define _IQtoQ15(A) ((short)((long)((A) * (1 << 15)))) +#define _Q15toIQ(A) (((float)(A)) * (1.0 / (1 << 15))) +#define _IQtoQ14(A) ((short)((long)((A) * (1 << 14)))) +#define _Q14toIQ(A) (((float)(A)) * (1.0 / (1 << 14))) +#define _IQtoQ13(A) ((short)((long)((A) * (1 << 13)))) +#define _Q13toIQ(A) (((float)(A)) * (1.0 / (1 << 13))) +#define _IQtoQ12(A) ((short)((long)((A) * (1 << 12)))) +#define _Q12toIQ(A) (((float)(A)) * (1.0 / (1 << 12))) +#define _IQtoQ11(A) ((short)((long)((A) * (1 << 11)))) +#define _Q11toIQ(A) (((float)(A)) * (1.0 / (1 << 11))) +#define _IQtoQ10(A) ((short)((long)((A) * (1 << 10)))) +#define _Q10toIQ(A) (((float)(A)) * (1.0 / (1 << 10))) +#define _IQtoQ9(A) ((short)((long)((A) * (1 << 9)))) +#define _Q9toIQ(A) (((float)(A)) * (1.0 / (1 << 9))) +#define _IQtoQ8(A) ((short)((long)((A) * (1 << 8)))) +#define _Q8toIQ(A) (((float)(A)) * (1.0 / (1 << 8))) +#define _IQtoQ7(A) ((short)((long)((A) * (1 << 7)))) +#define _Q7toIQ(A) (((float)(A)) * (1.0 / (1 << 7))) +#define _IQtoQ6(A) ((short)((long)((A) * (1 << 6)))) +#define _Q6toIQ(A) (((float)(A)) * (1.0 / (1 << 6))) +#define _IQtoQ5(A) ((short)((long)((A) * (1 << 5)))) +#define _Q5toIQ(A) (((float)(A)) * (1.0 / (1 << 5))) +#define _IQtoQ4(A) ((short)((long)((A) * (1 << 4)))) +#define _Q4toIQ(A) (((float)(A)) * (1.0 / (1 << 4))) +#define _IQtoQ3(A) ((short)((long)((A) * (1 << 3)))) +#define _Q3toIQ(A) (((float)(A)) * (1.0 / (1 << 3))) +#define _IQtoQ2(A) ((short)((long)((A) * (1 << 2)))) +#define _Q2toIQ(A) (((float)(A)) * (1.0 / (1 << 2))) +#define _IQtoQ1(A) ((short)((long)((A) * (1 << 1)))) +#define _Q1toIQ(A) (((float)(A)) * (1.0 / (1 << 1))) + +//***************************************************************************** +// +// Multiplies two IQ numbers. +// +//***************************************************************************** +#define _IQ30mpy(A, B) ((A) * (B)) +#define _IQ29mpy(A, B) ((A) * (B)) +#define _IQ28mpy(A, B) ((A) * (B)) +#define _IQ27mpy(A, B) ((A) * (B)) +#define _IQ26mpy(A, B) ((A) * (B)) +#define _IQ25mpy(A, B) ((A) * (B)) +#define _IQ24mpy(A, B) ((A) * (B)) +#define _IQ23mpy(A, B) ((A) * (B)) +#define _IQ22mpy(A, B) ((A) * (B)) +#define _IQ21mpy(A, B) ((A) * (B)) +#define _IQ20mpy(A, B) ((A) * (B)) +#define _IQ19mpy(A, B) ((A) * (B)) +#define _IQ18mpy(A, B) ((A) * (B)) +#define _IQ17mpy(A, B) ((A) * (B)) +#define _IQ16mpy(A, B) ((A) * (B)) +#define _IQ15mpy(A, B) ((A) * (B)) +#define _IQ14mpy(A, B) ((A) * (B)) +#define _IQ13mpy(A, B) ((A) * (B)) +#define _IQ12mpy(A, B) ((A) * (B)) +#define _IQ11mpy(A, B) ((A) * (B)) +#define _IQ10mpy(A, B) ((A) * (B)) +#define _IQ9mpy(A, B) ((A) * (B)) +#define _IQ8mpy(A, B) ((A) * (B)) +#define _IQ7mpy(A, B) ((A) * (B)) +#define _IQ6mpy(A, B) ((A) * (B)) +#define _IQ5mpy(A, B) ((A) * (B)) +#define _IQ4mpy(A, B) ((A) * (B)) +#define _IQ3mpy(A, B) ((A) * (B)) +#define _IQ2mpy(A, B) ((A) * (B)) +#define _IQ1mpy(A, B) ((A) * (B)) +#define _IQmpy(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding. +// +//***************************************************************************** +#define _IQ30rmpy(A, B) ((A) * (B)) +#define _IQ29rmpy(A, B) ((A) * (B)) +#define _IQ28rmpy(A, B) ((A) * (B)) +#define _IQ27rmpy(A, B) ((A) * (B)) +#define _IQ26rmpy(A, B) ((A) * (B)) +#define _IQ25rmpy(A, B) ((A) * (B)) +#define _IQ24rmpy(A, B) ((A) * (B)) +#define _IQ23rmpy(A, B) ((A) * (B)) +#define _IQ22rmpy(A, B) ((A) * (B)) +#define _IQ21rmpy(A, B) ((A) * (B)) +#define _IQ20rmpy(A, B) ((A) * (B)) +#define _IQ19rmpy(A, B) ((A) * (B)) +#define _IQ18rmpy(A, B) ((A) * (B)) +#define _IQ17rmpy(A, B) ((A) * (B)) +#define _IQ16rmpy(A, B) ((A) * (B)) +#define _IQ15rmpy(A, B) ((A) * (B)) +#define _IQ14rmpy(A, B) ((A) * (B)) +#define _IQ13rmpy(A, B) ((A) * (B)) +#define _IQ12rmpy(A, B) ((A) * (B)) +#define _IQ11rmpy(A, B) ((A) * (B)) +#define _IQ10rmpy(A, B) ((A) * (B)) +#define _IQ9rmpy(A, B) ((A) * (B)) +#define _IQ8rmpy(A, B) ((A) * (B)) +#define _IQ7rmpy(A, B) ((A) * (B)) +#define _IQ6rmpy(A, B) ((A) * (B)) +#define _IQ5rmpy(A, B) ((A) * (B)) +#define _IQ4rmpy(A, B) ((A) * (B)) +#define _IQ3rmpy(A, B) ((A) * (B)) +#define _IQ2rmpy(A, B) ((A) * (B)) +#define _IQ1rmpy(A, B) ((A) * (B)) +#define _IQrmpy(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies two IQ numbers, with rounding and saturation. +// +//***************************************************************************** +#define _IQ30rsmpy(A, B) ((A) * (B)) +#define _IQ29rsmpy(A, B) ((A) * (B)) +#define _IQ28rsmpy(A, B) ((A) * (B)) +#define _IQ27rsmpy(A, B) ((A) * (B)) +#define _IQ26rsmpy(A, B) ((A) * (B)) +#define _IQ25rsmpy(A, B) ((A) * (B)) +#define _IQ24rsmpy(A, B) ((A) * (B)) +#define _IQ23rsmpy(A, B) ((A) * (B)) +#define _IQ22rsmpy(A, B) ((A) * (B)) +#define _IQ21rsmpy(A, B) ((A) * (B)) +#define _IQ20rsmpy(A, B) ((A) * (B)) +#define _IQ19rsmpy(A, B) ((A) * (B)) +#define _IQ18rsmpy(A, B) ((A) * (B)) +#define _IQ17rsmpy(A, B) ((A) * (B)) +#define _IQ16rsmpy(A, B) ((A) * (B)) +#define _IQ15rsmpy(A, B) ((A) * (B)) +#define _IQ14rsmpy(A, B) ((A) * (B)) +#define _IQ13rsmpy(A, B) ((A) * (B)) +#define _IQ12rsmpy(A, B) ((A) * (B)) +#define _IQ11rsmpy(A, B) ((A) * (B)) +#define _IQ10rsmpy(A, B) ((A) * (B)) +#define _IQ9rsmpy(A, B) ((A) * (B)) +#define _IQ8rsmpy(A, B) ((A) * (B)) +#define _IQ7rsmpy(A, B) ((A) * (B)) +#define _IQ6rsmpy(A, B) ((A) * (B)) +#define _IQ5rsmpy(A, B) ((A) * (B)) +#define _IQ4rsmpy(A, B) ((A) * (B)) +#define _IQ3rsmpy(A, B) ((A) * (B)) +#define _IQ2rsmpy(A, B) ((A) * (B)) +#define _IQ1rsmpy(A, B) ((A) * (B)) +#define _IQrsmpy(A, B) ((A) * (B)) + +//***************************************************************************** +// +// Divides two IQ numbers. +// +//***************************************************************************** +#define _IQ30div(A, B) ((A) / (B)) +#define _IQ29div(A, B) ((A) / (B)) +#define _IQ28div(A, B) ((A) / (B)) +#define _IQ27div(A, B) ((A) / (B)) +#define _IQ26div(A, B) ((A) / (B)) +#define _IQ25div(A, B) ((A) / (B)) +#define _IQ24div(A, B) ((A) / (B)) +#define _IQ23div(A, B) ((A) / (B)) +#define _IQ22div(A, B) ((A) / (B)) +#define _IQ21div(A, B) ((A) / (B)) +#define _IQ20div(A, B) ((A) / (B)) +#define _IQ19div(A, B) ((A) / (B)) +#define _IQ18div(A, B) ((A) / (B)) +#define _IQ17div(A, B) ((A) / (B)) +#define _IQ16div(A, B) ((A) / (B)) +#define _IQ15div(A, B) ((A) / (B)) +#define _IQ14div(A, B) ((A) / (B)) +#define _IQ13div(A, B) ((A) / (B)) +#define _IQ12div(A, B) ((A) / (B)) +#define _IQ11div(A, B) ((A) / (B)) +#define _IQ10div(A, B) ((A) / (B)) +#define _IQ9div(A, B) ((A) / (B)) +#define _IQ8div(A, B) ((A) / (B)) +#define _IQ7div(A, B) ((A) / (B)) +#define _IQ6div(A, B) ((A) / (B)) +#define _IQ5div(A, B) ((A) / (B)) +#define _IQ4div(A, B) ((A) / (B)) +#define _IQ3div(A, B) ((A) / (B)) +#define _IQ2div(A, B) ((A) / (B)) +#define _IQ1div(A, B) ((A) / (B)) +#define _IQdiv(A, B) ((A) / (B)) + +//***************************************************************************** +// +// Computes the sin of an IQ number. +// +//***************************************************************************** +#define _IQ29sin(A) sin(A) +#define _IQ28sin(A) sin(A) +#define _IQ27sin(A) sin(A) +#define _IQ26sin(A) sin(A) +#define _IQ25sin(A) sin(A) +#define _IQ24sin(A) sin(A) +#define _IQ23sin(A) sin(A) +#define _IQ22sin(A) sin(A) +#define _IQ21sin(A) sin(A) +#define _IQ20sin(A) sin(A) +#define _IQ19sin(A) sin(A) +#define _IQ18sin(A) sin(A) +#define _IQ17sin(A) sin(A) +#define _IQ16sin(A) sin(A) +#define _IQ15sin(A) sin(A) +#define _IQ14sin(A) sin(A) +#define _IQ13sin(A) sin(A) +#define _IQ12sin(A) sin(A) +#define _IQ11sin(A) sin(A) +#define _IQ10sin(A) sin(A) +#define _IQ9sin(A) sin(A) +#define _IQ8sin(A) sin(A) +#define _IQ7sin(A) sin(A) +#define _IQ6sin(A) sin(A) +#define _IQ5sin(A) sin(A) +#define _IQ4sin(A) sin(A) +#define _IQ3sin(A) sin(A) +#define _IQ2sin(A) sin(A) +#define _IQ1sin(A) sin(A) +#define _IQsin(A) sin(A) + +//***************************************************************************** +// +// Computes the sin of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +#define _IQ30sinPU(A) sin((A) * 6.283185307) +#define _IQ29sinPU(A) sin((A) * 6.283185307) +#define _IQ28sinPU(A) sin((A) * 6.283185307) +#define _IQ27sinPU(A) sin((A) * 6.283185307) +#define _IQ26sinPU(A) sin((A) * 6.283185307) +#define _IQ25sinPU(A) sin((A) * 6.283185307) +#define _IQ24sinPU(A) sin((A) * 6.283185307) +#define _IQ23sinPU(A) sin((A) * 6.283185307) +#define _IQ22sinPU(A) sin((A) * 6.283185307) +#define _IQ21sinPU(A) sin((A) * 6.283185307) +#define _IQ20sinPU(A) sin((A) * 6.283185307) +#define _IQ19sinPU(A) sin((A) * 6.283185307) +#define _IQ18sinPU(A) sin((A) * 6.283185307) +#define _IQ17sinPU(A) sin((A) * 6.283185307) +#define _IQ16sinPU(A) sin((A) * 6.283185307) +#define _IQ15sinPU(A) sin((A) * 6.283185307) +#define _IQ14sinPU(A) sin((A) * 6.283185307) +#define _IQ13sinPU(A) sin((A) * 6.283185307) +#define _IQ12sinPU(A) sin((A) * 6.283185307) +#define _IQ11sinPU(A) sin((A) * 6.283185307) +#define _IQ10sinPU(A) sin((A) * 6.283185307) +#define _IQ9sinPU(A) sin((A) * 6.283185307) +#define _IQ8sinPU(A) sin((A) * 6.283185307) +#define _IQ7sinPU(A) sin((A) * 6.283185307) +#define _IQ6sinPU(A) sin((A) * 6.283185307) +#define _IQ5sinPU(A) sin((A) * 6.283185307) +#define _IQ4sinPU(A) sin((A) * 6.283185307) +#define _IQ3sinPU(A) sin((A) * 6.283185307) +#define _IQ2sinPU(A) sin((A) * 6.283185307) +#define _IQ1sinPU(A) sin((A) * 6.283185307) +#define _IQsinPU(A) sin((A) * 6.283185307) + +//***************************************************************************** +// +// Computes the arcsin of an IQ number. +// +//***************************************************************************** +#define _IQ29asin(A) asin(A) +#define _IQ28asin(A) asin(A) +#define _IQ27asin(A) asin(A) +#define _IQ26asin(A) asin(A) +#define _IQ25asin(A) asin(A) +#define _IQ24asin(A) asin(A) +#define _IQ23asin(A) asin(A) +#define _IQ22asin(A) asin(A) +#define _IQ21asin(A) asin(A) +#define _IQ20asin(A) asin(A) +#define _IQ19asin(A) asin(A) +#define _IQ18asin(A) asin(A) +#define _IQ17asin(A) asin(A) +#define _IQ16asin(A) asin(A) +#define _IQ15asin(A) asin(A) +#define _IQ14asin(A) asin(A) +#define _IQ13asin(A) asin(A) +#define _IQ12asin(A) asin(A) +#define _IQ11asin(A) asin(A) +#define _IQ10asin(A) asin(A) +#define _IQ9asin(A) asin(A) +#define _IQ8asin(A) asin(A) +#define _IQ7asin(A) asin(A) +#define _IQ6asin(A) asin(A) +#define _IQ5asin(A) asin(A) +#define _IQ4asin(A) asin(A) +#define _IQ3asin(A) asin(A) +#define _IQ2asin(A) asin(A) +#define _IQ1asin(A) asin(A) +#define _IQasin(A) asin(A) + +//***************************************************************************** +// +// Computes the cos of an IQ number. +// +//***************************************************************************** +#define _IQ29cos(A) cos(A) +#define _IQ28cos(A) cos(A) +#define _IQ27cos(A) cos(A) +#define _IQ26cos(A) cos(A) +#define _IQ25cos(A) cos(A) +#define _IQ24cos(A) cos(A) +#define _IQ23cos(A) cos(A) +#define _IQ22cos(A) cos(A) +#define _IQ21cos(A) cos(A) +#define _IQ20cos(A) cos(A) +#define _IQ19cos(A) cos(A) +#define _IQ18cos(A) cos(A) +#define _IQ17cos(A) cos(A) +#define _IQ16cos(A) cos(A) +#define _IQ15cos(A) cos(A) +#define _IQ14cos(A) cos(A) +#define _IQ13cos(A) cos(A) +#define _IQ12cos(A) cos(A) +#define _IQ11cos(A) cos(A) +#define _IQ10cos(A) cos(A) +#define _IQ9cos(A) cos(A) +#define _IQ8cos(A) cos(A) +#define _IQ7cos(A) cos(A) +#define _IQ6cos(A) cos(A) +#define _IQ5cos(A) cos(A) +#define _IQ4cos(A) cos(A) +#define _IQ3cos(A) cos(A) +#define _IQ2cos(A) cos(A) +#define _IQ1cos(A) cos(A) +#define _IQcos(A) cos(A) + +//***************************************************************************** +// +// Computes the cos of an IQ number, using cycles per unit instead of radians. +// +//***************************************************************************** +#define _IQ30cosPU(A) cos((A) * 6.283185307) +#define _IQ29cosPU(A) cos((A) * 6.283185307) +#define _IQ28cosPU(A) cos((A) * 6.283185307) +#define _IQ27cosPU(A) cos((A) * 6.283185307) +#define _IQ26cosPU(A) cos((A) * 6.283185307) +#define _IQ25cosPU(A) cos((A) * 6.283185307) +#define _IQ24cosPU(A) cos((A) * 6.283185307) +#define _IQ23cosPU(A) cos((A) * 6.283185307) +#define _IQ22cosPU(A) cos((A) * 6.283185307) +#define _IQ21cosPU(A) cos((A) * 6.283185307) +#define _IQ20cosPU(A) cos((A) * 6.283185307) +#define _IQ19cosPU(A) cos((A) * 6.283185307) +#define _IQ18cosPU(A) cos((A) * 6.283185307) +#define _IQ17cosPU(A) cos((A) * 6.283185307) +#define _IQ16cosPU(A) cos((A) * 6.283185307) +#define _IQ15cosPU(A) cos((A) * 6.283185307) +#define _IQ14cosPU(A) cos((A) * 6.283185307) +#define _IQ13cosPU(A) cos((A) * 6.283185307) +#define _IQ12cosPU(A) cos((A) * 6.283185307) +#define _IQ11cosPU(A) cos((A) * 6.283185307) +#define _IQ10cosPU(A) cos((A) * 6.283185307) +#define _IQ9cosPU(A) cos((A) * 6.283185307) +#define _IQ8cosPU(A) cos((A) * 6.283185307) +#define _IQ7cosPU(A) cos((A) * 6.283185307) +#define _IQ6cosPU(A) cos((A) * 6.283185307) +#define _IQ5cosPU(A) cos((A) * 6.283185307) +#define _IQ4cosPU(A) cos((A) * 6.283185307) +#define _IQ3cosPU(A) cos((A) * 6.283185307) +#define _IQ2cosPU(A) cos((A) * 6.283185307) +#define _IQ1cosPU(A) cos((A) * 6.283185307) +#define _IQcosPU(A) cos((A) * 6.283185307) + +//***************************************************************************** +// +// Computes the arccos of an IQ number. +// +//***************************************************************************** +#define _IQ29acos(A) acos(A) +#define _IQ28acos(A) acos(A) +#define _IQ27acos(A) acos(A) +#define _IQ26acos(A) acos(A) +#define _IQ25acos(A) acos(A) +#define _IQ24acos(A) acos(A) +#define _IQ23acos(A) acos(A) +#define _IQ22acos(A) acos(A) +#define _IQ21acos(A) acos(A) +#define _IQ20acos(A) acos(A) +#define _IQ19acos(A) acos(A) +#define _IQ18acos(A) acos(A) +#define _IQ17acos(A) acos(A) +#define _IQ16acos(A) acos(A) +#define _IQ15acos(A) acos(A) +#define _IQ14acos(A) acos(A) +#define _IQ13acos(A) acos(A) +#define _IQ12acos(A) acos(A) +#define _IQ11acos(A) acos(A) +#define _IQ10acos(A) acos(A) +#define _IQ9acos(A) acos(A) +#define _IQ8acos(A) acos(A) +#define _IQ7acos(A) acos(A) +#define _IQ6acos(A) acos(A) +#define _IQ5acos(A) acos(A) +#define _IQ4acos(A) acos(A) +#define _IQ3acos(A) acos(A) +#define _IQ2acos(A) acos(A) +#define _IQ1acos(A) acos(A) +#define _IQacos(A) acos(A) + +//***************************************************************************** +// +// Computes the arctan of an IQ number. +// +//***************************************************************************** +#define _IQ29atan(A) atan(A) +#define _IQ28atan(A) atan(A) +#define _IQ27atan(A) atan(A) +#define _IQ26atan(A) atan(A) +#define _IQ25atan(A) atan(A) +#define _IQ24atan(A) atan(A) +#define _IQ23atan(A) atan(A) +#define _IQ22atan(A) atan(A) +#define _IQ21atan(A) atan(A) +#define _IQ20atan(A) atan(A) +#define _IQ19atan(A) atan(A) +#define _IQ18atan(A) atan(A) +#define _IQ17atan(A) atan(A) +#define _IQ16atan(A) atan(A) +#define _IQ15atan(A) atan(A) +#define _IQ14atan(A) atan(A) +#define _IQ13atan(A) atan(A) +#define _IQ12atan(A) atan(A) +#define _IQ11atan(A) atan(A) +#define _IQ10atan(A) atan(A) +#define _IQ9atan(A) atan(A) +#define _IQ8atan(A) atan(A) +#define _IQ7atan(A) atan(A) +#define _IQ6atan(A) atan(A) +#define _IQ5atan(A) atan(A) +#define _IQ4atan(A) atan(A) +#define _IQ3atan(A) atan(A) +#define _IQ2atan(A) atan(A) +#define _IQ1atan(A) atan(A) +#define _IQatan(A) atan(A) + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers. +// +//***************************************************************************** +#define _IQ30atan2(A, B) atan2(A, B) +#define _IQ29atan2(A, B) atan2(A, B) +#define _IQ28atan2(A, B) atan2(A, B) +#define _IQ27atan2(A, B) atan2(A, B) +#define _IQ26atan2(A, B) atan2(A, B) +#define _IQ25atan2(A, B) atan2(A, B) +#define _IQ24atan2(A, B) atan2(A, B) +#define _IQ23atan2(A, B) atan2(A, B) +#define _IQ22atan2(A, B) atan2(A, B) +#define _IQ21atan2(A, B) atan2(A, B) +#define _IQ20atan2(A, B) atan2(A, B) +#define _IQ19atan2(A, B) atan2(A, B) +#define _IQ18atan2(A, B) atan2(A, B) +#define _IQ17atan2(A, B) atan2(A, B) +#define _IQ16atan2(A, B) atan2(A, B) +#define _IQ15atan2(A, B) atan2(A, B) +#define _IQ14atan2(A, B) atan2(A, B) +#define _IQ13atan2(A, B) atan2(A, B) +#define _IQ12atan2(A, B) atan2(A, B) +#define _IQ11atan2(A, B) atan2(A, B) +#define _IQ10atan2(A, B) atan2(A, B) +#define _IQ9atan2(A, B) atan2(A, B) +#define _IQ8atan2(A, B) atan2(A, B) +#define _IQ7atan2(A, B) atan2(A, B) +#define _IQ6atan2(A, B) atan2(A, B) +#define _IQ5atan2(A, B) atan2(A, B) +#define _IQ4atan2(A, B) atan2(A, B) +#define _IQ3atan2(A, B) atan2(A, B) +#define _IQ2atan2(A, B) atan2(A, B) +#define _IQ1atan2(A, B) atan2(A, B) +#define _IQatan2(A, B) atan2(A, B) + +//***************************************************************************** +// +// Computes the arctan of a coordinate specified by two IQ numbers, returning +// the value in cycles per unit instead of radians. +// +//***************************************************************************** +#define _IQ30atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ29atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ28atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ27atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ26atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ25atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ24atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ23atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ22atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ21atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ20atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ19atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ18atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ17atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ16atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ15atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ14atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ13atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ12atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ11atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ10atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ9atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ8atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ7atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ6atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ5atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ4atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ3atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ2atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQ1atan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) +#define _IQatan2PU(A, B) (((atan2(A, B) * (1.0 / 6.283185307)) >= \ + 0.0) ? \ + (atan2(A, B) * (1.0 / 6.283185307)) : \ + (atan2(A, B) * (1.0 / 6.283185307) + 1.0)) + +//***************************************************************************** +// +// Computes the square root of an IQ number. +// +//***************************************************************************** +#define _IQ30sqrt(A) sqrt(A) +#define _IQ29sqrt(A) sqrt(A) +#define _IQ28sqrt(A) sqrt(A) +#define _IQ27sqrt(A) sqrt(A) +#define _IQ26sqrt(A) sqrt(A) +#define _IQ25sqrt(A) sqrt(A) +#define _IQ24sqrt(A) sqrt(A) +#define _IQ23sqrt(A) sqrt(A) +#define _IQ22sqrt(A) sqrt(A) +#define _IQ21sqrt(A) sqrt(A) +#define _IQ20sqrt(A) sqrt(A) +#define _IQ19sqrt(A) sqrt(A) +#define _IQ18sqrt(A) sqrt(A) +#define _IQ17sqrt(A) sqrt(A) +#define _IQ16sqrt(A) sqrt(A) +#define _IQ15sqrt(A) sqrt(A) +#define _IQ14sqrt(A) sqrt(A) +#define _IQ13sqrt(A) sqrt(A) +#define _IQ12sqrt(A) sqrt(A) +#define _IQ11sqrt(A) sqrt(A) +#define _IQ10sqrt(A) sqrt(A) +#define _IQ9sqrt(A) sqrt(A) +#define _IQ8sqrt(A) sqrt(A) +#define _IQ7sqrt(A) sqrt(A) +#define _IQ6sqrt(A) sqrt(A) +#define _IQ5sqrt(A) sqrt(A) +#define _IQ4sqrt(A) sqrt(A) +#define _IQ3sqrt(A) sqrt(A) +#define _IQ2sqrt(A) sqrt(A) +#define _IQ1sqrt(A) sqrt(A) +#define _IQsqrt(A) sqrt(A) + +//***************************************************************************** +// +// Computes 1 over the square root of an IQ number. +// +//***************************************************************************** +#define _IQ30isqrt(A) (1.0 / sqrt(A)) +#define _IQ29isqrt(A) (1.0 / sqrt(A)) +#define _IQ28isqrt(A) (1.0 / sqrt(A)) +#define _IQ27isqrt(A) (1.0 / sqrt(A)) +#define _IQ26isqrt(A) (1.0 / sqrt(A)) +#define _IQ25isqrt(A) (1.0 / sqrt(A)) +#define _IQ24isqrt(A) (1.0 / sqrt(A)) +#define _IQ23isqrt(A) (1.0 / sqrt(A)) +#define _IQ22isqrt(A) (1.0 / sqrt(A)) +#define _IQ21isqrt(A) (1.0 / sqrt(A)) +#define _IQ20isqrt(A) (1.0 / sqrt(A)) +#define _IQ19isqrt(A) (1.0 / sqrt(A)) +#define _IQ18isqrt(A) (1.0 / sqrt(A)) +#define _IQ17isqrt(A) (1.0 / sqrt(A)) +#define _IQ16isqrt(A) (1.0 / sqrt(A)) +#define _IQ15isqrt(A) (1.0 / sqrt(A)) +#define _IQ14isqrt(A) (1.0 / sqrt(A)) +#define _IQ13isqrt(A) (1.0 / sqrt(A)) +#define _IQ12isqrt(A) (1.0 / sqrt(A)) +#define _IQ11isqrt(A) (1.0 / sqrt(A)) +#define _IQ10isqrt(A) (1.0 / sqrt(A)) +#define _IQ9isqrt(A) (1.0 / sqrt(A)) +#define _IQ8isqrt(A) (1.0 / sqrt(A)) +#define _IQ7isqrt(A) (1.0 / sqrt(A)) +#define _IQ6isqrt(A) (1.0 / sqrt(A)) +#define _IQ5isqrt(A) (1.0 / sqrt(A)) +#define _IQ4isqrt(A) (1.0 / sqrt(A)) +#define _IQ3isqrt(A) (1.0 / sqrt(A)) +#define _IQ2isqrt(A) (1.0 / sqrt(A)) +#define _IQ1isqrt(A) (1.0 / sqrt(A)) +#define _IQisqrt(A) (1.0 / sqrt(A)) + +//***************************************************************************** +// +// Computes e^x of an IQ number. +// +//***************************************************************************** +#define _IQ30exp(A) exp(A) +#define _IQ29exp(A) exp(A) +#define _IQ28exp(A) exp(A) +#define _IQ27exp(A) exp(A) +#define _IQ26exp(A) exp(A) +#define _IQ25exp(A) exp(A) +#define _IQ24exp(A) exp(A) +#define _IQ23exp(A) exp(A) +#define _IQ22exp(A) exp(A) +#define _IQ21exp(A) exp(A) +#define _IQ20exp(A) exp(A) +#define _IQ19exp(A) exp(A) +#define _IQ18exp(A) exp(A) +#define _IQ17exp(A) exp(A) +#define _IQ16exp(A) exp(A) +#define _IQ15exp(A) exp(A) +#define _IQ14exp(A) exp(A) +#define _IQ13exp(A) exp(A) +#define _IQ12exp(A) exp(A) +#define _IQ11exp(A) exp(A) +#define _IQ10exp(A) exp(A) +#define _IQ9exp(A) exp(A) +#define _IQ8exp(A) exp(A) +#define _IQ7exp(A) exp(A) +#define _IQ6exp(A) exp(A) +#define _IQ5exp(A) exp(A) +#define _IQ4exp(A) exp(A) +#define _IQ3exp(A) exp(A) +#define _IQ2exp(A) exp(A) +#define _IQ1exp(A) exp(A) +#define _IQexp(A) exp(A) + +//***************************************************************************** +// +// Computes 2^x of an IQ number. +// +//***************************************************************************** +#define _IQ30exp2(A) exp2(A) +#define _IQ29exp2(A) exp2(A) +#define _IQ28exp2(A) exp2(A) +#define _IQ27exp2(A) exp2(A) +#define _IQ26exp2(A) exp2(A) +#define _IQ25exp2(A) exp2(A) +#define _IQ24exp2(A) exp2(A) +#define _IQ23exp2(A) exp2(A) +#define _IQ22exp2(A) exp2(A) +#define _IQ21exp2(A) exp2(A) +#define _IQ20exp2(A) exp2(A) +#define _IQ19exp2(A) exp2(A) +#define _IQ18exp2(A) exp2(A) +#define _IQ17exp2(A) exp2(A) +#define _IQ16exp2(A) exp2(A) +#define _IQ15exp2(A) exp2(A) +#define _IQ14exp2(A) exp2(A) +#define _IQ13exp2(A) exp2(A) +#define _IQ12exp2(A) exp2(A) +#define _IQ11exp2(A) exp2(A) +#define _IQ10exp2(A) exp2(A) +#define _IQ9exp2(A) exp2(A) +#define _IQ8exp2(A) exp2(A) +#define _IQ7exp2(A) exp2(A) +#define _IQ6exp2(A) exp2(A) +#define _IQ5exp2(A) exp2(A) +#define _IQ4exp2(A) exp2(A) +#define _IQ3exp2(A) exp2(A) +#define _IQ2exp2(A) exp2(A) +#define _IQ1exp2(A) exp2(A) +#define _IQexp2(A) exp2(A) + +//***************************************************************************** +// +// Returns the integer portion of an IQ number. +// +//***************************************************************************** +#define _IQ30int(A) ((long)(A)) +#define _IQ29int(A) ((long)(A)) +#define _IQ28int(A) ((long)(A)) +#define _IQ27int(A) ((long)(A)) +#define _IQ26int(A) ((long)(A)) +#define _IQ25int(A) ((long)(A)) +#define _IQ24int(A) ((long)(A)) +#define _IQ23int(A) ((long)(A)) +#define _IQ22int(A) ((long)(A)) +#define _IQ21int(A) ((long)(A)) +#define _IQ20int(A) ((long)(A)) +#define _IQ19int(A) ((long)(A)) +#define _IQ18int(A) ((long)(A)) +#define _IQ17int(A) ((long)(A)) +#define _IQ16int(A) ((long)(A)) +#define _IQ15int(A) ((long)(A)) +#define _IQ14int(A) ((long)(A)) +#define _IQ13int(A) ((long)(A)) +#define _IQ12int(A) ((long)(A)) +#define _IQ11int(A) ((long)(A)) +#define _IQ10int(A) ((long)(A)) +#define _IQ9int(A) ((long)(A)) +#define _IQ8int(A) ((long)(A)) +#define _IQ7int(A) ((long)(A)) +#define _IQ6int(A) ((long)(A)) +#define _IQ5int(A) ((long)(A)) +#define _IQ4int(A) ((long)(A)) +#define _IQ3int(A) ((long)(A)) +#define _IQ2int(A) ((long)(A)) +#define _IQ1int(A) ((long)(A)) +#define _IQint(A) ((long)(A)) + +//***************************************************************************** +// +// Computes the fractional portion of an IQ number. +// +//***************************************************************************** +#define _IQ30frac(A) ((A) - (float)((long)(A))) +#define _IQ29frac(A) ((A) - (float)((long)(A))) +#define _IQ28frac(A) ((A) - (float)((long)(A))) +#define _IQ27frac(A) ((A) - (float)((long)(A))) +#define _IQ26frac(A) ((A) - (float)((long)(A))) +#define _IQ25frac(A) ((A) - (float)((long)(A))) +#define _IQ24frac(A) ((A) - (float)((long)(A))) +#define _IQ23frac(A) ((A) - (float)((long)(A))) +#define _IQ22frac(A) ((A) - (float)((long)(A))) +#define _IQ21frac(A) ((A) - (float)((long)(A))) +#define _IQ20frac(A) ((A) - (float)((long)(A))) +#define _IQ19frac(A) ((A) - (float)((long)(A))) +#define _IQ18frac(A) ((A) - (float)((long)(A))) +#define _IQ17frac(A) ((A) - (float)((long)(A))) +#define _IQ16frac(A) ((A) - (float)((long)(A))) +#define _IQ15frac(A) ((A) - (float)((long)(A))) +#define _IQ14frac(A) ((A) - (float)((long)(A))) +#define _IQ13frac(A) ((A) - (float)((long)(A))) +#define _IQ12frac(A) ((A) - (float)((long)(A))) +#define _IQ11frac(A) ((A) - (float)((long)(A))) +#define _IQ10frac(A) ((A) - (float)((long)(A))) +#define _IQ9frac(A) ((A) - (float)((long)(A))) +#define _IQ8frac(A) ((A) - (float)((long)(A))) +#define _IQ7frac(A) ((A) - (float)((long)(A))) +#define _IQ6frac(A) ((A) - (float)((long)(A))) +#define _IQ5frac(A) ((A) - (float)((long)(A))) +#define _IQ4frac(A) ((A) - (float)((long)(A))) +#define _IQ3frac(A) ((A) - (float)((long)(A))) +#define _IQ2frac(A) ((A) - (float)((long)(A))) +#define _IQ1frac(A) ((A) - (float)((long)(A))) +#define _IQfrac(A) ((A) - (float)((long)(A))) + +//***************************************************************************** +// +// Multiplies two IQ numbers in the specified IQ formats, returning the result +// in another IQ format. +// +//***************************************************************************** +#define _IQ30mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ29mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ28mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ27mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ26mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ25mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ24mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ23mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ22mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ21mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ20mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ19mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ18mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ17mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ16mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ15mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ14mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ13mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ12mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ11mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ10mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ9mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ8mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ7mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ6mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ5mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ4mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ3mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ2mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQ1mpyIQX(A, IQA, B, IQB) ((A) * (B)) +#define _IQmpyIQX(A, IQA, B, IQB) ((A) * (B)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer. +// +//***************************************************************************** +#define _IQ30mpyI32(A, B) ((A) * (float)(B)) +#define _IQ29mpyI32(A, B) ((A) * (float)(B)) +#define _IQ28mpyI32(A, B) ((A) * (float)(B)) +#define _IQ27mpyI32(A, B) ((A) * (float)(B)) +#define _IQ26mpyI32(A, B) ((A) * (float)(B)) +#define _IQ25mpyI32(A, B) ((A) * (float)(B)) +#define _IQ24mpyI32(A, B) ((A) * (float)(B)) +#define _IQ23mpyI32(A, B) ((A) * (float)(B)) +#define _IQ22mpyI32(A, B) ((A) * (float)(B)) +#define _IQ21mpyI32(A, B) ((A) * (float)(B)) +#define _IQ20mpyI32(A, B) ((A) * (float)(B)) +#define _IQ19mpyI32(A, B) ((A) * (float)(B)) +#define _IQ18mpyI32(A, B) ((A) * (float)(B)) +#define _IQ17mpyI32(A, B) ((A) * (float)(B)) +#define _IQ16mpyI32(A, B) ((A) * (float)(B)) +#define _IQ15mpyI32(A, B) ((A) * (float)(B)) +#define _IQ14mpyI32(A, B) ((A) * (float)(B)) +#define _IQ13mpyI32(A, B) ((A) * (float)(B)) +#define _IQ12mpyI32(A, B) ((A) * (float)(B)) +#define _IQ11mpyI32(A, B) ((A) * (float)(B)) +#define _IQ10mpyI32(A, B) ((A) * (float)(B)) +#define _IQ9mpyI32(A, B) ((A) * (float)(B)) +#define _IQ8mpyI32(A, B) ((A) * (float)(B)) +#define _IQ7mpyI32(A, B) ((A) * (float)(B)) +#define _IQ6mpyI32(A, B) ((A) * (float)(B)) +#define _IQ5mpyI32(A, B) ((A) * (float)(B)) +#define _IQ4mpyI32(A, B) ((A) * (float)(B)) +#define _IQ3mpyI32(A, B) ((A) * (float)(B)) +#define _IQ2mpyI32(A, B) ((A) * (float)(B)) +#define _IQ1mpyI32(A, B) ((A) * (float)(B)) +#define _IQmpyI32(A, B) ((A) * (float)(B)) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the integer portion. +// +//***************************************************************************** +#define _IQ30mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ29mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ28mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ27mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ26mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ25mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ24mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ23mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ22mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ21mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ20mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ19mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ18mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ17mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ16mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ15mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ14mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ13mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ12mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ11mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ10mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ9mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ8mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ7mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ6mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ5mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ4mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ3mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ2mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQ1mpyI32int(A, B) ((long)((A) * (float)(B))) +#define _IQmpyI32int(A, B) ((long)((A) * (float)(B))) + +//***************************************************************************** +// +// Multiplies an IQ number by an integer, and returns the fractional portion. +// +//***************************************************************************** +#define _IQ30mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ29mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ28mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ27mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ26mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ25mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ24mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ23mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ22mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ21mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ20mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ19mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ18mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ17mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ16mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ15mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ14mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ13mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ12mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ11mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ10mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ9mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ8mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ7mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ6mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ5mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ4mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ3mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ2mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQ1mpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) +#define _IQmpyI32frac(A, B) (((A) * (B)) - \ + (float)((long)((A) * (float)(B)))) + +//***************************************************************************** +// +// Computes the square root of A^2 + B^2 using IQ numbers. +// +//***************************************************************************** +#define _IQ30mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ29mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ28mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ27mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ26mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ25mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ24mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ23mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ22mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ21mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ20mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ19mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ18mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ17mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ16mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ15mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ14mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ13mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ12mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ11mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ10mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ9mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ8mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ7mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ6mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ5mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ4mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ3mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ2mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQ1mag(A, B) sqrt(((A) * (A)) + ((B) * (B))) +#define _IQmag(A, B) sqrt(((A) * (A)) + ((B) * (B))) + +//***************************************************************************** +// +// Converts a string into an IQ number. +// +//***************************************************************************** +#define _atoIQ30(A) atof(A) +#define _atoIQ29(A) atof(A) +#define _atoIQ28(A) atof(A) +#define _atoIQ27(A) atof(A) +#define _atoIQ26(A) atof(A) +#define _atoIQ25(A) atof(A) +#define _atoIQ24(A) atof(A) +#define _atoIQ23(A) atof(A) +#define _atoIQ22(A) atof(A) +#define _atoIQ21(A) atof(A) +#define _atoIQ20(A) atof(A) +#define _atoIQ19(A) atof(A) +#define _atoIQ18(A) atof(A) +#define _atoIQ17(A) atof(A) +#define _atoIQ16(A) atof(A) +#define _atoIQ15(A) atof(A) +#define _atoIQ14(A) atof(A) +#define _atoIQ13(A) atof(A) +#define _atoIQ12(A) atof(A) +#define _atoIQ11(A) atof(A) +#define _atoIQ10(A) atof(A) +#define _atoIQ9(A) atof(A) +#define _atoIQ8(A) atof(A) +#define _atoIQ7(A) atof(A) +#define _atoIQ6(A) atof(A) +#define _atoIQ5(A) atof(A) +#define _atoIQ4(A) atof(A) +#define _atoIQ3(A) atof(A) +#define _atoIQ2(A) atof(A) +#define _atoIQ1(A) atof(A) +#define _atoIQ(A) atof(A) + +//***************************************************************************** +// +// Converts an IQ number into a string. +// +//***************************************************************************** +#define _IQ30toa(A, B, C) sprintf(A, B, C) +#define _IQ29toa(A, B, C) sprintf(A, B, C) +#define _IQ28toa(A, B, C) sprintf(A, B, C) +#define _IQ27toa(A, B, C) sprintf(A, B, C) +#define _IQ26toa(A, B, C) sprintf(A, B, C) +#define _IQ25toa(A, B, C) sprintf(A, B, C) +#define _IQ24toa(A, B, C) sprintf(A, B, C) +#define _IQ23toa(A, B, C) sprintf(A, B, C) +#define _IQ22toa(A, B, C) sprintf(A, B, C) +#define _IQ21toa(A, B, C) sprintf(A, B, C) +#define _IQ20toa(A, B, C) sprintf(A, B, C) +#define _IQ19toa(A, B, C) sprintf(A, B, C) +#define _IQ18toa(A, B, C) sprintf(A, B, C) +#define _IQ17toa(A, B, C) sprintf(A, B, C) +#define _IQ16toa(A, B, C) sprintf(A, B, C) +#define _IQ15toa(A, B, C) sprintf(A, B, C) +#define _IQ14toa(A, B, C) sprintf(A, B, C) +#define _IQ13toa(A, B, C) sprintf(A, B, C) +#define _IQ12toa(A, B, C) sprintf(A, B, C) +#define _IQ11toa(A, B, C) sprintf(A, B, C) +#define _IQ10toa(A, B, C) sprintf(A, B, C) +#define _IQ9toa(A, B, C) sprintf(A, B, C) +#define _IQ8toa(A, B, C) sprintf(A, B, C) +#define _IQ7toa(A, B, C) sprintf(A, B, C) +#define _IQ6toa(A, B, C) sprintf(A, B, C) +#define _IQ5toa(A, B, C) sprintf(A, B, C) +#define _IQ4toa(A, B, C) sprintf(A, B, C) +#define _IQ3toa(A, B, C) sprintf(A, B, C) +#define _IQ2toa(A, B, C) sprintf(A, B, C) +#define _IQ1toa(A, B, C) sprintf(A, B, C) +#define _IQtoa(A, B, C) sprintf(A, B, C) + +//***************************************************************************** +// +// Computes the absolute value of an IQ number. +// +//***************************************************************************** +#define _IQ30abs(A) fabs(A) +#define _IQ29abs(A) fabs(A) +#define _IQ28abs(A) fabs(A) +#define _IQ27abs(A) fabs(A) +#define _IQ26abs(A) fabs(A) +#define _IQ25abs(A) fabs(A) +#define _IQ24abs(A) fabs(A) +#define _IQ23abs(A) fabs(A) +#define _IQ22abs(A) fabs(A) +#define _IQ21abs(A) fabs(A) +#define _IQ20abs(A) fabs(A) +#define _IQ19abs(A) fabs(A) +#define _IQ18abs(A) fabs(A) +#define _IQ17abs(A) fabs(A) +#define _IQ16abs(A) fabs(A) +#define _IQ15abs(A) fabs(A) +#define _IQ14abs(A) fabs(A) +#define _IQ13abs(A) fabs(A) +#define _IQ12abs(A) fabs(A) +#define _IQ11abs(A) fabs(A) +#define _IQ10abs(A) fabs(A) +#define _IQ9abs(A) fabs(A) +#define _IQ8abs(A) fabs(A) +#define _IQ7abs(A) fabs(A) +#define _IQ6abs(A) fabs(A) +#define _IQ5abs(A) fabs(A) +#define _IQ4abs(A) fabs(A) +#define _IQ3abs(A) fabs(A) +#define _IQ2abs(A) fabs(A) +#define _IQ1abs(A) fabs(A) +#define _IQabs(A) fabs(A) + +#endif // MATH_TYPE == IQ_MATH + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __IQMATHLIB_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/Makefile b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9aa8ba657bac8512093a16573ab0872521b8c653 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/Makefile @@ -0,0 +1,33 @@ +#****************************************************************************** +# +# Makefile - A convenience makefile for internal use building IQmath. +# +# Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. +# Software License Agreement +# +# Texas Instruments (TI) is supplying this software for use solely and +# exclusively on TI's microcontroller products. The software is owned by +# TI and/or its suppliers, and is protected under applicable copyright +# laws. You may not combine this software with "viral" open-source +# software in order to form a larger program. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +# NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +# NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +# CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +# DAMAGES, FOR ANY REASON WHATSOEVER. +# +# This is part of revision 2.1.4.178 of the Tiva IQmath Library. +# +#****************************************************************************** + +all: + @make -f Makefile.IQmathLib + +clean: + @make -f Makefile.IQmathLib clean + +realclean: + @make -f Makefile.IQmathLib realclean + @make -f Makefile.lmi clean diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ccs/IQmathLib/Debug/IQmathLib.lib b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ccs/IQmathLib/Debug/IQmathLib.lib new file mode 100644 index 0000000000000000000000000000000000000000..0b946a841de16fffe24fc50c47ad1cb931dd52db Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ccs/IQmathLib/Debug/IQmathLib.lib differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ewarm/Exe/IQmathLib.a b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ewarm/Exe/IQmathLib.a new file mode 100644 index 0000000000000000000000000000000000000000..0f1affe30b952af93cadb774144a015fc987d618 Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/ewarm/Exe/IQmathLib.a differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/gcc/IQmathLib.a b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/gcc/IQmathLib.a new file mode 100644 index 0000000000000000000000000000000000000000..e9a6735ea7c61fd076e44174172944408ffb4cac Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/gcc/IQmathLib.a differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/rvmdk/IQmathLib.lib b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/rvmdk/IQmathLib.lib new file mode 100644 index 0000000000000000000000000000000000000000..845adda138987f6463c8fec19aee7147e949ce31 Binary files /dev/null and b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/IQmath/rvmdk/IQmathLib.lib differ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/MANIFEST.txt b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/MANIFEST.txt new file mode 100644 index 0000000000000000000000000000000000000000..37f0079ec1ef71a3c3b49aec098bd4fc94a414e7 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/MANIFEST.txt @@ -0,0 +1,359 @@ +Manifest for Texas Instruments TivaWare Clickwrap License Agreement + +TivaWare version 2.1.4.178 + +Legend (explanation of the fields in the Manifest table below) + +Software Name: The name of the application or file + +Version: Version of the application or file + +License Type: Type of license(s) under which TI will be providing software to +the licensee (e.g. BSD, GPLv2, TI TSPA License, TI Commercial License). See +Open Source Reference License Disclaimer in the Disclaimers Section. + +Location: The directory name and path on the media (or in an archive) where the +Software is located. + +Delivered As: This field will either be "Source", "Binary" or "Source and +Binary" and is the form the content of the Software is delivered in. If the +Software is delivered in an archive format, this field applies to the contents +of the archive. If the word Limited is used with Source, as in "Limited Source" +or "Limited Source and Binary" then only portions of the Source for the +application are provided. + +Modified by TI: This field will either be "Yes" or "No". A "Yes" means TI has +made changes to the Software. A "No" means TI has not made any changes. Note: +This field is not applicable for Software "Obtained from" TI. + +Obtained from: This field specifies from where or from whom TI obtained the +Software. It may be a URL to an Open Source site, a 3rd party licensor, or TI +(if TI developed the software). If this field contains a link to Open Source +software, the date TI downloaded the Software is also recorded. See Links +Disclaimer in the Disclaimers Section. + +DISCLAIMERS + +Export Control Classification Number (ECCN) + +Any use of ECCNs listed in the Manifest is at the user's risk and without +recourse to TI. Your company, as the exporter of record, is responsible for +determining the correct classification of any item at the time of export. Any +export classification by TI of Software is for TI's internal use only and shall +not be construed as a representation or warranty regarding the proper export +classification for such Software or whether an export license or other +documentation is required for exporting such Software. + +Links in the Manifest + +Any links appearing on this Manifest (for example in the "Obtained from" field) +were verified at the time the Manifest was created. TI makes no guarantee that +any listed links will remain active in the future. + +Open Source License Reference + +Your company is responsible for confirming the applicable license terms for any +open source Software listed in this Manifest that was not "Obtained from" TI. +Any open source license specified in this Manifest for Software that was not +"Obtained from" TI is for TI's internal use only and shall not be construed as +a representation or warranty regarding the proper open source license terms for +such Software. + +Export Information + +ECCN for Software included in this release: Publicly Available + +ECCN for Technology (e.g., user documentation, specifications) included in this +release: Publicly Available + +Manifest + +See Legend above for a description of the fields and possible values. + + + +Software Name: TivaWare make definitions +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./makedefs +Obtained From: TI + +Software Name: TivaWare master Makefile +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./Makefile +Obtained From: TI + +Software Name: Tiva Boot Loader +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./boot_loader +Obtained From: TI + +Software Name: JSON Parser +Version: N/A +License Type: MIT +Delivered As: Source +Modified by TI: Yes +Location: ./cc3100-sdk/examples/common +Obtained From: https://bitbucket.org/zserge/jsmn/src/http://zserge.com/jsmn.html + +Software Name: HTTP Client Library +Version: 1.00.01.04 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./cc3100-sdk/netapps/http +Obtained From: TI + +Software Name: MQTT Library +Version: 1.1.0 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./cc3100-sdk/netapps/mqtt +Obtained From: TI + +Software Name: CC3100 Drivers +Version: 1.1.0 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./cc3100-sdk/platform +Obtained From: TI + +Software Name: CC3100 Host Driver +Version: N/A +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./cc3100-sdk/simplelink +Obtained From: TI + +Software Name: Simplelink Extlib +Version: 1.1.0 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./cc3100-sdk/simplelink_extlib +Obtained From: TI + +Software Name: Tiva Peripheral Driver Library +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./driverlib +Obtained From: TI + +Software Name: Tiva Examples Makefile +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./examples/Makefile +Obtained From: TI + +Software Name: Tiva Board Examples +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./examples/boards +Obtained From: TI + +Software Name: Tiva Peripheral Examples +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./examples/peripherals +Obtained From: TI + +Software Name: Tiva Project Example +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./examples/project +Obtained From: TI + +Software Name: Tiva Graphics Library +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./grlib +Obtained From: TI + +Software Name: Tiva Device Header Files +Version: 2.1.4.178 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: N/A +Location: ./inc +Obtained From: TI + +Software Name: TI IQmath Fixed Point Library +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Binary +Modified by TI: N/A +Location: ./IQmath +Obtained From: TI + +Software Name: TI NFC Network Stack +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./nfclib +Obtained From: TI + +Software Name: Tiva Sensor Library +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./sensorlib +Obtained From: TI + +Software Name: Host tools +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./tools +Obtained From: TI + +Software Name: Tiva USB Library +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./usblib +Obtained From: TI + +Software Name: Utility Functions +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./utils +Obtained From: TI + +Software Name: Custom Windows Drivers +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Binary +Modified by TI: N/A +Location: ./windows_drivers +Obtained From: TI + +Software Name: BGET Heap Allocator +Version: October 1995 +License Type: Public domain +Delivered As: Source +Modified by TI: No +Location: ./third_party/bget +Obtained From: http://www.fourmilab.ch/bget/ + +Software Name: Exosite Library +Version: N/A +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: Yes +Location: ./third_party/exosite +Obtained From: Exosite LLC + +Software Name: FatFs FAT File System +Version: 0.04b +License Type: FatFS +Delivered As: Source +Modified by TI: Yes - porting code added +Location: ./third_party/fatfs +Obtained From: http://elm-chan.org/fsw/ff/00index_e.html + +Software Name: Firefly Sung Font +Version: 1.3.0 +License Type: Arphic Public License +Delivered As: Source +Modified by TI: No +Location: ./third_party/fonts/apl +Obtained From: http://www.study-area.org/apt/firefly-font/ + +Software Name: Custom Font Generation Demo +Version: 2.1.4.178 +License Type: TI Commercial +Delivered As: Source +Modified by TI: N/A +Location: ./third_party/fonts/lang_demo +Obtained From: N/A + +Software Name: Various OFL Fonts +Version: N/A +License Type: Open Font License +License Type: http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL +Delivered As: Source +Modified by TI: No +Location: ./third_party/fonts/ofl +Obtained From: OldStandard - http://www.thessalonica.org.ru/en/fonts-download.html +Obtained From: Theano - http://www.thessalonica.org.ru/en/fonts-download.html +Obtained From: Andika - http://www.sil.org/computing/catalog/show_software.asp?id=119 +Obtained From: Breip - http://helloalan.com/projects/breip/ +Obtained From: Nanum - http://hangeul.naver.com/download.nhn + +Software Name: Other Fonts +Version: N/A +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: No +Location: ./third_party/fonts/other +Obtained From: (Sazanami) http://sourceforge.jp/projects/efont/releases/#10087 + +Software Name: FreeRTOS +Version: 8.2.3 +License Type: GPL-2-0 with linking exception +Delivered As: Source +Modified by TI: Yes - Removed support for non-TM4C Devices +Location: ./third_party/FreeRTOS +Obtained From: http://sourceforge.net/projects/freertos/files/FreeRTOS/V8.2.3 + +Software Name: LWIP Network Stack +Version: 1.4.1 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: Yes - porting code added +Location: ./third_party/lwip-1.4.1 +Obtained From: http://savannah.nongnu.org/projects/lwip/ + +Software Name: PTP Daemon +Version: 1.1.0 +License Type: BSD-2-Clause +Delivered As: Source +Modified by TI: Yes - porting code added +Location: ./third_party/ptpd-1.1.0 +Obtained From: http://sourceforge.net/projects/ptpd/files/ptpd/ + +Software Name: UIP Network Stack +Version: 1.0 +License Type: BSD-3-Clause +Delivered As: Source +Modified by TI: No +Location: ./third_party/uip-1.0 +Obtained From: http://www.sics.se/~adam/old-uip/download.html + +Software Name: Fast Light Toolkit +Version: 1.1.10 +License Type: LGPL-2-0 with linking exception +Delivered As: Source +Modified by TI: No +Location: ./third_party/windows/fltk-1.1.10 +Obtained From: http://www.fltk.org/software.php + \ No newline at end of file diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/Makefile b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..30bc2653c350f9fab80fa52816e23cb2ee40aeee --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/Makefile @@ -0,0 +1,64 @@ +#****************************************************************************** +# +# Makefile - Rules for building the driver library and examples. +# +# Copyright (c) 2005-2017 Texas Instruments Incorporated. All rights reserved. +# Software License Agreement +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# Neither the name of Texas Instruments Incorporated nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +# +#****************************************************************************** + +DIRS=driverlib \ + grlib \ + sensorlib \ + usblib \ + examples + +all:: + @for i in ${DIRS}; \ + do \ + if [ -f $${i}/Makefile ]; \ + then \ + make -C $${i} || exit $$?; \ + fi; \ + done + +clean:: + @rm -f ${wildcard *~} __dummy__ + @rm -f ${wildcard utils/*~} __dummy__ + @for i in ${DIRS}; \ + do \ + if [ -f $${i}/Makefile ]; \ + then \ + make -C $${i} clean; \ + fi; \ + done diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/TI-BSD-EULA.txt b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/TI-BSD-EULA.txt new file mode 100644 index 0000000000000000000000000000000000000000..7d9b839d824ca60e3963809b1a64c1194f497e7b --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/TI-BSD-EULA.txt @@ -0,0 +1,29 @@ +Software License Agreement + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the original copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the original copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_autobaud.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_autobaud.c new file mode 100644 index 0000000000000000000000000000000000000000..0e0ba080a92f2f7601b7a0590088f9b2406cbe31 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_autobaud.c @@ -0,0 +1,279 @@ +//***************************************************************************** +// +// bl_autobaud.c - Automatic baud rate detection code. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" +#include "bl_config.h" +#include "boot_loader/bl_uart.h" + +//***************************************************************************** +// +// If using auto-baud, make sure that the data buffer is large enough. +// +//***************************************************************************** +#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) && (BUFFER_SIZE < 20) +#error ERROR: BUFFER_SIZE must be >= 20! +#endif + +//***************************************************************************** +// +//! \addtogroup bl_autobaud_api +//! @{ +// +//***************************************************************************** +#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) || defined(DOXYGEN) + +//***************************************************************************** +// +// This define holds the multiplier for the pulse detection algorithm. The +// value is used to generate a fractional difference detection of +// 1 / PULSE_DETECTION_MULT. +// +//***************************************************************************** +#define PULSE_DETECTION_MULT 3 + +//***************************************************************************** +// +// This define holds the minimum number of edges to successfully sync to a +// pattern of 2 bytes. +// +//***************************************************************************** +#define MIN_EDGE_COUNT 18 + +//***************************************************************************** +// +// This global holds the number of edges that have been stored in the global +// buffer g_pui32DataBuffer. +// +//***************************************************************************** +static volatile uint32_t g_ui32TickIndex; + +//***************************************************************************** +// +// The data buffer that is used for receiving packets is used to hold the edge +// times during auto-baud. The buffer is not used for receiving packets while +// auto-baud is in progress, so this does not present problems. +// +//***************************************************************************** +extern uint32_t g_pui32DataBuffer[]; + +//***************************************************************************** +// +//! Handles the UART Rx GPIO interrupt. +//! +//! When an edge is detected on the UART Rx pin, this function is called to +//! save the time of the edge. These times are later used to determine the +//! ratio of the UART baud rate to the processor clock rate. +//! +//! \return None. +// +//***************************************************************************** +void +GPIOIntHandler(void) +{ + uint32_t ui32Temp; + + // + // Clear the GPIO interrupt source. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_ICR) = UART_RX; + + // + // While we still have space in our buffer, store the current system tick + // count and return from interrupt. + // + if(g_ui32TickIndex < 20) + { + ui32Temp = HWREG(NVIC_ST_CURRENT); + g_pui32DataBuffer[g_ui32TickIndex++] = ui32Temp; + } +} + +//***************************************************************************** +// +//! Performs auto-baud on the UART port. +//! +//! \param pui32Ratio is the ratio of the processor's crystal frequency to the +//! baud rate being used by the UART port for communications. +//! +//! This function attempts to synchronize to the updater program that is trying +//! to communicate with the boot loader. The UART port is monitored for edges +//! using interrupts. Once enough edges are detected, the boot loader +//! determines the ratio of baud rate and crystal frequency needed to program +//! the UART. +//! +//! \return Returns a value of 0 to indicate that this call successfully +//! synchronized with the other device communicating over the UART, and a +//! negative value to indicate that this function did not successfully +//! synchronize with the other UART device. +// +//***************************************************************************** +int +UARTAutoBaud(uint32_t *pui32Ratio) +{ + int32_t i32Pulse, i32ValidPulses, i32Temp, i32Total; + volatile int32_t i32Delay; + + // + // Configure and enable SysTick. Set the reload value to the maximum; + // there are only 24 bits in the register but loading 32 bits of ones is + // more efficient. + // + HWREG(NVIC_ST_RELOAD) = 0xffffffff; + HWREG(NVIC_ST_CTRL) = NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE; + + // + // Reset the counters that control the pulse detection. + // + i32ValidPulses = 0; + i32Total = 0; + g_ui32TickIndex = 0; + + // + // Set the pad(s) for standard push-pull operation. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_PUR) |= UART_RX; + HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_RX; + + // + // Interrupt on both edges. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_IBE) = UART_RX; + + // + // Clear out all of the gpio interrupts in this register. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_ICR) = UART_RX; + + // + // Enable the GPIO pin corresponding to the UART RX pin. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_IM) = UART_RX; + + // + // Enable GPIOA Interrupt. + // + HWREG(NVIC_EN0) = 1; + + // + // Wait for MIN_EDGE_COUNT to pass to collect enough edges. + // + while(g_ui32TickIndex < MIN_EDGE_COUNT) + { + } + + // + // Disable GPIOA Interrupt. + // + HWREG(NVIC_DIS0) = 1; + + // + // Calculate the pulse widths from the array of tick times. + // + for(i32Pulse = 0; i32Pulse < (MIN_EDGE_COUNT - 1); i32Pulse++) + { + i32Temp = (((int32_t)g_pui32DataBuffer[i32Pulse] - + (int32_t)g_pui32DataBuffer[i32Pulse + 1]) & 0x00ffffff); + g_pui32DataBuffer[i32Pulse] = i32Temp; + } + + // + // This loops handles checking for consecutive pulses that have pulse + // widths that are within an acceptable margin. + // + for(i32Pulse = 0; i32Pulse < (MIN_EDGE_COUNT - 1); i32Pulse++) + { + // + // Calculate the absolute difference between two consecutive pulses. + // + i32Temp = (int32_t)g_pui32DataBuffer[i32Pulse]; + i32Temp -= (int32_t)g_pui32DataBuffer[i32Pulse + 1]; + if(i32Temp < 0) + { + i32Temp *= -1; + } + + // + // This pulse detection code uses the following algorithm: + // If the following is true then we have consecutive acceptable pulses + // abs(Pulse[n] - Pulse[n + 1]) < Pulse[n + 1] / PULSE_DETECTION_MULT + // or + // PULSE_DETECTION_MULT * abs(Pulse[n] - Pulse[n + 1]) < Pulse[n + 1] + // + if((i32Temp * PULSE_DETECTION_MULT) < + (int32_t)g_pui32DataBuffer[i32Pulse + 1]) + { + i32Total += (int32_t)g_pui32DataBuffer[i32Pulse]; + i32ValidPulses++; + } + else + { + i32ValidPulses = 0; + i32Total = 0; + } + + // + // Once we have 7 pulses calculate the ratio needed to program the + // UART. + // + if(i32ValidPulses == 7) + { + // + // Add in the last pulse and calculate the ratio. + // + i32Total += (int32_t)g_pui32DataBuffer[i32Pulse]; + *pui32Ratio = i32Total >> 1; + + // + // Wait for at least 2 UART clocks since we only wait for 18 of 20 + // that are coming from the host. If we don't wait, we can turn + // on the UART while the last two pulses come down. + // + for(i32Delay = i32Total; i32Delay; i32Delay--) + { + } + + // + // Indicate a successful auto baud operation. + // + return(0); + } + } + + // + // Automatic baud rate detection failed. + // + return(-1); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.c new file mode 100644 index 0000000000000000000000000000000000000000..6aaffffdfc27fcdb38766dc8a7d4b1aba78d3e77 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.c @@ -0,0 +1,1454 @@ +//***************************************************************************** +// +// bl_can.c - Functions to transfer data via the CAN port. +// +// Copyright (c) 2008-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_can.h" +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "inc/hw_flash.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "inc/hw_uart.h" +#include "bl_config.h" +#include "boot_loader/bl_can.h" +#include "boot_loader/bl_can_timing.h" +#include "boot_loader/bl_check.h" +#include "boot_loader/bl_crystal.h" +#include "boot_loader/bl_flash.h" +#include "boot_loader/bl_hooks.h" +#include "boot_loader/bl_uart.h" + +//***************************************************************************** +// +//! \addtogroup bl_can_api +//! @{ +// +//***************************************************************************** +#if defined(CAN_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +// The results that can be returned by the CAN APIs. +// +//***************************************************************************** +#define CAN_CMD_SUCCESS 0x00 +#define CAN_CMD_FAIL 0x01 + +//***************************************************************************** +// +// Macros used to generate correct pin definitions. +// +//***************************************************************************** +#define CAN_RX_PIN_M (1 << CAN_RX_PIN) +#define CAN_TX_PIN_M (1 << CAN_TX_PIN) +#define CAN_RX_PIN_PCTL_M (CAN_RX_PIN_PCTL << (CAN_RX_PIN*4)) +#define CAN_TX_PIN_PCTL_M (CAN_TX_PIN_PCTL << (CAN_TX_PIN*4)) + +//***************************************************************************** +// +// Convenience macros for accessing CAN registers. +// +//***************************************************************************** +#define CANRegWrite(ui32Address, ui32Value) \ + HWREG(ui32Address) = ui32Value + +#define CANRegRead(ui32Address) \ + HWREG(ui32Address) + +//***************************************************************************** +// +// The message object number and index to the local message object memory to +// use when accessing the messages. +// +//***************************************************************************** +#define MSG_OBJ_BCAST_RX_ID 1 +#define MSG_OBJ_BCAST_TX_ID 2 + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for calling the +// application. +// +//***************************************************************************** +extern void StartApplication(void); + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for a predictable length +// delay. +// +//***************************************************************************** +extern void Delay(uint32_t ui32Count); + +//***************************************************************************** +// +// Holds the current address to write to when data is received via the Send +// Data Command. +// +//***************************************************************************** +static uint32_t g_ui32TransferAddress; + +//***************************************************************************** +// +// Holds the remaining bytes expected to be received. +// +//***************************************************************************** +static uint32_t g_ui32TransferSize; + +//***************************************************************************** +// +// The buffer used to receive data from the update. +// +//***************************************************************************** +static uint8_t g_pui8CommandBuffer[8]; + +//***************************************************************************** +// +// These globals are used to store the first two words to prevent a partial +// image from being booted. +// +//***************************************************************************** +static uint32_t g_ui32StartValues[2]; +static uint32_t g_ui32StartSize; +static uint32_t g_ui32StartAddress; + +//***************************************************************************** +// +// The active interface when the UART bridge is enabled. +// +//***************************************************************************** +#ifdef CAN_UART_BRIDGE +static uint32_t g_ui32Interface; +#define IFACE_UNKNOWN 0 +#define IFACE_CAN 1 +#define IFACE_UART 2 +#endif + +//***************************************************************************** +// +//! Initializes the CAN controller after reset. +//! +//! After reset, the CAN controller is left in the disabled state. However, +//! the memory used for message objects contains undefined values and must be +//! cleared prior to enabling the CAN controller the first time. This prevents +//! unwanted transmission or reception of data before the message objects are +//! configured. This function must be called before enabling the controller +//! the first time. +//! +//! \return None. +// +//***************************************************************************** +static void +CANInit(void) +{ + int iMsg; + + // + // Place CAN controller in init state, regardless of previous state. This + // will put the controller in idle, and allow the message object RAM to be + // programmed. + // + CANRegWrite(CAN0_BASE + CAN_O_CTL, CAN_CTL_INIT | CAN_CTL_CCE); + + // + // Loop through to program all 32 message objects + // + for(iMsg = 1; iMsg <= 32; iMsg++) + { + // + // Wait for busy bit to clear. + // + while(CANRegRead(CAN0_BASE + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) + { + } + + // + // Clear the message value bit in the arbitration register. This + // indicates the message is not valid and is a "safe" condition to + // leave the message object. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CMSK, + CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_ARB | CAN_IF1CMSK_CONTROL); + CANRegWrite(CAN0_BASE + CAN_O_IF1ARB2, 0); + CANRegWrite(CAN0_BASE + CAN_O_IF1MCTL, 0); + + // + // Initiate programming of the message object + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CRQ, iMsg); + } + + // + // Acknowledge any pending status interrupts. + // + CANRegRead(CAN0_BASE + CAN_O_STS); +} + +//***************************************************************************** +// +//! This function configures the message object used to receive commands. +//! +//! This function configures the message object used to receive all firmware +//! update messages. This will not actually read the data from the message it +//! is used to prepare the message object to receive the data when it is sent. +//! +//! \return None. +// +//***************************************************************************** +static void +CANMessageSetRx(void) +{ + uint16_t ui16CmdMaskReg; + uint16_t ui16MaskReg[2]; + uint16_t ui16ArbReg[2]; + uint16_t ui16MsgCtrl; + + // + // Wait for busy bit to clear + // + while(CANRegRead(CAN0_BASE + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) + { + } + + // + // This is always a write to the Message object as this call is setting a + // message object. This call will also always set all size bits so it sets + // both data bits. The call will use the CONTROL register to set control + // bits so this bit needs to be set as well. + // + // Set the MASK bit so that this gets transferred to the Message Object. + // Set the Arb bit so that this gets transferred to the Message object. + // + ui16CmdMaskReg = (CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_DATAA | + CAN_IF1CMSK_DATAB | CAN_IF1CMSK_CONTROL | + CAN_IF1CMSK_MASK | CAN_IF1CMSK_ARB); + + // + // Set the UMASK bit to enable using the mask register. + // Set the data length since this is set for all transfers. This is also a + // single transfer and not a FIFO transfer so set EOB bit. + // + ui16MsgCtrl = CAN_IF1MCTL_UMASK | CAN_IF1MCTL_EOB; + + // + // Configure the Mask Registers. + // + // + // Set the 29 bits of Identifier mask that were requested. + // + ui16MaskReg[0] = (uint16_t)LM_API_UPD; + + // + // If the caller wants to filter on the extended ID bit then set it. + // + ui16MaskReg[1] = + (uint16_t)(CAN_IF1MSK2_MXTD | (LM_API_UPD >> 16)); + + // + // Set the 29 bit version of the Identifier for this message object. + // Mark the message as valid and set the extended ID bit. + // + ui16ArbReg[0] = LM_API_UPD & CAN_IF1ARB1_ID_M; + ui16ArbReg[1] = (((LM_API_UPD >> 16) & CAN_IF1ARB2_ID_M) | + (CAN_IF1ARB2_MSGVAL | CAN_IF1ARB2_XTD)); + + // + // Write out the registers to program the message object. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CMSK, ui16CmdMaskReg); + CANRegWrite(CAN0_BASE + CAN_O_IF1MSK1, ui16MaskReg[0]); + CANRegWrite(CAN0_BASE + CAN_O_IF1MSK2, ui16MaskReg[1]); + CANRegWrite(CAN0_BASE + CAN_O_IF1ARB1, ui16ArbReg[0]); + CANRegWrite(CAN0_BASE + CAN_O_IF1ARB2, ui16ArbReg[1]); + CANRegWrite(CAN0_BASE + CAN_O_IF1MCTL, ui16MsgCtrl); + + // + // Transfer the message object to the message object specific by + // MSG_OBJ_BCAST_RX_ID. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CRQ, + MSG_OBJ_BCAST_RX_ID & CAN_IF1CRQ_MNUM_M); +} + +//***************************************************************************** +// +//! This function reads data from the receive message object. +//! +//! \param pui8Data is a pointer to the buffer to store the data read from the +//! CAN controller. +//! \param pui32MsgID is a pointer to the ID that was received with the data. +//! +//! This function will reads and acknowledges the data read from the message +//! object used to receive all CAN firmware update messages. It will also +//! return the message identifier as this holds the API number that was +//! attached to the data. This message identifier should be one of the +//! LM_API_UPD_* definitions. +//! +//! \return The number of valid bytes returned in the \e pui8Data buffer or +//! 0xffffffff if data was overwritten in the buffer. +// +//***************************************************************************** +static uint32_t +CANMessageGetRx(uint8_t *pui8Data, uint32_t *pui32MsgID) +{ + uint16_t ui16CmdMaskReg; + uint16_t ui16ArbReg0, ui16ArbReg1; + uint16_t ui16MsgCtrl; + uint32_t ui32Bytes; + uint16_t *pui16Data; + + // + // This is always a read to the Message object as this call is setting a + // message object. + // Clear a pending interrupt and new data in a message object. + // + ui16CmdMaskReg = (CAN_IF2CMSK_DATAA | CAN_IF2CMSK_DATAB | + CAN_IF1CMSK_CONTROL | CAN_IF2CMSK_CLRINTPND | + CAN_IF2CMSK_ARB); + + // + // Set up the request for data from the message object. + // + CANRegWrite(CAN0_BASE + CAN_O_IF2CMSK, ui16CmdMaskReg); + + // + // Transfer the message object to the message object specific by + // MSG_OBJ_BCAST_RX_ID. + // + CANRegWrite(CAN0_BASE + CAN_O_IF2CRQ, + MSG_OBJ_BCAST_RX_ID & CAN_IF1CRQ_MNUM_M); + + // + // Wait for busy bit to clear + // + while(CANRegRead(CAN0_BASE + CAN_O_IF2CRQ) & CAN_IF1CRQ_BUSY) + { + } + + // + // Read out the IF Registers. + // + ui16ArbReg0 = CANRegRead(CAN0_BASE + CAN_O_IF2ARB1); + ui16ArbReg1 = CANRegRead(CAN0_BASE + CAN_O_IF2ARB2); + ui16MsgCtrl = CANRegRead(CAN0_BASE + CAN_O_IF2MCTL); + + // + // Set the 29 bit version of the Identifier for this message object. + // + *pui32MsgID = ((ui16ArbReg1 & CAN_IF1ARB2_ID_M) << 16) | ui16ArbReg0; + + // + // See if there is new data available. + // + if((ui16MsgCtrl & (CAN_IF1MCTL_NEWDAT | CAN_IF1MCTL_MSGLST)) == + CAN_IF1MCTL_NEWDAT) + { + // + // Get the amount of data needed to be read. + // + ui32Bytes = ui16MsgCtrl & CAN_IF1MCTL_DLC_M; + + // + // Read out the data from the CAN registers 16 bits at a time. + // + pui16Data = (uint16_t *)pui8Data; + + pui16Data[0] = CANRegRead(CAN0_BASE + CAN_O_IF2DA1); + pui16Data[1] = CANRegRead(CAN0_BASE + CAN_O_IF2DA2); + pui16Data[2] = CANRegRead(CAN0_BASE + CAN_O_IF2DB1); + pui16Data[3] = CANRegRead(CAN0_BASE + CAN_O_IF2DB2); + + // + // Now clear out the new data flag. + // + CANRegWrite(CAN0_BASE + CAN_O_IF2CMSK, CAN_IF1CMSK_NEWDAT); + + // + // Transfer the message object to the message object specific by + // MSG_OBJ_BCAST_RX_ID. + // + CANRegWrite(CAN0_BASE + CAN_O_IF2CRQ, MSG_OBJ_BCAST_RX_ID); + + // + // Wait for busy bit to clear + // + while(CANRegRead(CAN0_BASE + CAN_O_IF2CRQ) & CAN_IF2CRQ_BUSY) + { + } + } + else + { + // + // Data was lost so inform the caller. + // + ui32Bytes = 0xffffffff; + } + return(ui32Bytes); +} + +//***************************************************************************** +// +//! This function sends data using the transmit message object. +//! +//! \param ui32Id is the ID to use with this message. +//! \param pui8Data is a pointer to the buffer with the data to be sent. +//! \param ui32Size is the number of bytes to send and should not be more than +//! 8 bytes. +//! +//! This function will reads and acknowledges the data read from the message +//! object used to receive all CAN firmware update messages. It will also +//! return the message identifier as this holds the API number that was +//! attached to the data. This message identifier should be one of the +//! LM_API_UPD_* definitions. +//! +//! \return None. +// +//***************************************************************************** +static void +CANMessageSetTx(uint32_t ui32Id, const uint8_t *pui8Data, uint32_t ui32Size) +{ + uint16_t ui16CmdMaskReg; + uint16_t ui16ArbReg0, ui16ArbReg1; + uint16_t ui16MsgCtrl; + uint16_t *pui16Data; + + // + // Wait for busy bit to clear + // + while(CANRegRead(CAN0_BASE + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) + { + } + + // + // This is always a write to the Message object as this call is setting a + // message object. This call will also always set all size bits so it sets + // both data bits. The call will use the CONTROL register to set control + // bits so this bit needs to be set as well. + // + ui16CmdMaskReg = (CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_DATAA | + CAN_IF1CMSK_DATAB | CAN_IF1CMSK_CONTROL | + CAN_IF1CMSK_ARB); + + // + // Set the 29 bit version of the Identifier for this message object. + // + ui16ArbReg0 = ui32Id & CAN_IF1ARB1_ID_M; + + // + // Mark the message as valid and set the extended ID bit. + // + ui16ArbReg1 = (((ui32Id >> 16) & CAN_IF1ARB2_ID_M) | + (CAN_IF1ARB2_DIR | CAN_IF1ARB2_MSGVAL | CAN_IF1ARB2_XTD)); + + // + // Set the TXRQST bit and the reset the rest of the register. + // Set the data length since this is set for all transfers. This is also a + // single transfer and not a FIFO transfer so set EOB bit. + // + // + ui16MsgCtrl = (CAN_IF1MCTL_TXRQST | CAN_IF1MCTL_EOB | + (ui32Size & CAN_IF1MCTL_DLC_M)); + + pui16Data = (uint16_t *)pui8Data; + + // + // Write the data out to the CAN Data registers if needed. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1DA1, pui16Data[0]); + CANRegWrite(CAN0_BASE + CAN_O_IF1DA2, pui16Data[1]); + CANRegWrite(CAN0_BASE + CAN_O_IF1DB1, pui16Data[2]); + CANRegWrite(CAN0_BASE + CAN_O_IF1DB2, pui16Data[3]); + + // + // Write out the registers to program the message object. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CMSK, ui16CmdMaskReg); + CANRegWrite(CAN0_BASE + CAN_O_IF1ARB1, ui16ArbReg0); + CANRegWrite(CAN0_BASE + CAN_O_IF1ARB2, ui16ArbReg1); + CANRegWrite(CAN0_BASE + CAN_O_IF1MCTL, ui16MsgCtrl); + + // + // Transfer the message object to the message object specifiec by + // MSG_OBJ_BCAST_RX_ID. + // + CANRegWrite(CAN0_BASE + CAN_O_IF1CRQ, + (MSG_OBJ_BCAST_TX_ID) & CAN_IF1CRQ_MNUM_M); +} + +//***************************************************************************** +// +//! Configures the CAN interface. +//! +//! \param ui32SetTiming determines if the CAN bit timing should be configured. +//! +//! This function configures the CAN controller, preparing it for use by +//! the boot loader. If the \e ui32SetTiming parameter is 0, the bit timing +//! for the CAN bus will be left alone. This occurs when the boot loader was +//! entered from a running application that already has configured the timing +//! for the system. When \e ui32SetTiming is non-zero the bit timing will be +//! set to the defaults defined in the bl_config.h file in the +//! project. +//! +//! \return None. +// +//***************************************************************************** +static void +ConfigureCANInterface(uint32_t ui32SetTiming) +{ + // + // Reset the state of all the message object and the state of the CAN + // module to a known state. + // + CANInit(); + + // + // If a device identifier was specified then this was due to an update from + // a running CAN application so don't change the CAN bit timing. + // + if(ui32SetTiming != 0) + { + // + // Set the bit fields of the bit timing register according to the + // parms. + // + CANRegWrite(CAN0_BASE + CAN_O_BIT, CAN_BIT_TIMING); + + // + // Set the divider upper bits in the extension register. + // + CANRegWrite(CAN0_BASE + CAN_O_BRPE, 0); + } + + // + // Take the CAN0 device out of INIT state. + // + CANRegWrite(CAN0_BASE + CAN_O_CTL, 0); + + // + // Configure the broadcast receive message object. + // + CANMessageSetRx(); +} + +//***************************************************************************** +// +// Reads the next packet that is sent to the boot loader. +// +//***************************************************************************** +static uint32_t +PacketRead(uint8_t *pui8Data, uint32_t *pui32Size) +{ + uint32_t ui32MsgID; + +#ifdef CAN_UART_BRIDGE + uint32_t ui32Size, ui32Length, ui32Mode, ui32Char; + uint8_t pui8Buffer[12]; + + // + // Initialize the size and length of the packet. + // + ui32Length = 0; + ui32Size = 0; + + // + // If no interface has been determined then wait for either CAN or UART + // data until either responds. + // + if(g_ui32Interface == IFACE_UNKNOWN) + { + // + // Wait for CAN or UART data. + // + while((CANRegRead(CAN0_BASE + CAN_O_NWDA1) == 0) && + ((HWREG(UART0_BASE + UART_O_FR) & UART_FR_RXFE) == UART_FR_RXFE)) + { + } + + // + // If the UART FIFO was empty then the loop exited due to a CAN + // message. + // + if((HWREG(UART0_BASE + UART_O_FR) & UART_FR_RXFE) == UART_FR_RXFE) + { + g_ui32Interface = IFACE_CAN; + } + else + { + // + // The UART FIFO was not empty so the UART interface was used. + // + g_ui32Interface = IFACE_UART; + } + } + + // + // Read a data packet from the CAN controller. + // + if(g_ui32Interface == IFACE_CAN) + { +#endif + // + // Wait until a packet has been received. + // + while(CANRegRead(CAN0_BASE + CAN_O_NWDA1) == 0) + { + } + + // + // Read the packet. + // + *pui32Size = CANMessageGetRx(pui8Data, &ui32MsgID); +#ifdef CAN_UART_BRIDGE + } + else + { + // + // Read a data packet from the UART controller. + // + ui32Mode = 0; + + while(1) + { + // + // Wait until a char is available. + // + while(HWREG(UART0_BASE + UART_O_FR) & UART_FR_RXFE) + { + } + + // + // Now get the char. + // + ui32Char = HWREG(UART0_BASE + UART_O_DR); + + if(ui32Char == 0xff) + { + ui32Mode = 1; + ui32Length = 0; + } + else if(ui32Mode == 1) + { + if(ui32Char > 12) + { + ui32Mode = 0; + } + else + { + ui32Size = ui32Char; + ui32Mode = 2; + } + } + else if(ui32Mode == 3) + { + if(ui32Char == 0xfe) + { + pui8Buffer[ui32Length++] = 0xff; + ui32Mode = 2; + } + else if(ui32Char == 0xfd) + { + pui8Buffer[ui32Length++] = 0xfe; + ui32Mode = 2; + } + else + { + ui32Mode = 0; + } + } + else if(ui32Mode == 2) + { + if(ui32Char == 0xfe) + { + ui32Mode = 3; + } + else + { + pui8Buffer[ui32Length++] = ui32Char; + } + } + + if((ui32Length == ui32Size) && (ui32Mode == 2)) + { + ui32MsgID = *(uint32_t *)pui8Buffer; + + if((ui32MsgID & (CAN_MSGID_MFR_M | CAN_MSGID_DTYPE_M)) == + LM_API_UPD) + { + *(uint32_t *)pui8Data = + *(uint32_t *)(pui8Buffer + 4); + *(uint32_t *)(pui8Data + 4) = + *(uint32_t *)(pui8Buffer + 8); + *pui32Size = ui32Size - 4; + break; + } + } + } + } +#endif + + // + // Return the message ID of the packet that was received. + // + return(ui32MsgID); +} + +//***************************************************************************** +// +// This function writes out an individual character over the UART and +// handles sending out special sequences for handling 0xff and 0xfe values. +// +//***************************************************************************** +#ifdef CAN_UART_BRIDGE +static void +UARTBridgeWrite(uint32_t ui32Char) +{ + // + // See if the character being sent is 0xff. + // + if(ui32Char == 0xff) + { + // + // Send 0xfe 0xfe, the escaped version of 0xff. A sign extended + // version of 0xfe is used to avoid the check below for 0xfe, thereby + // avoiding an infinite loop. Only the lower 8 bits are actually sent, + // so 0xfe is what is actually transmitted. + // + UARTBridgeWrite(0xfffffffe); + UARTBridgeWrite(0xfffffffe); + } + + // + // Otherwise, see if the character being sent is 0xfe. + // + else if(ui32Char == 0xfe) + { + // + // Send 0xfe 0xfd, the escaped version of 0xfe. A sign extended + // version of 0xfe is used to avoid the check above for 0xfe, thereby + // avoiding an infinite loop. Only the lower 8 bits are actually sent, + // so 0xfe is what is actually transmitted. + // + UARTBridgeWrite(0xfffffffe); + UARTBridgeWrite(0xfd); + } + + // + // Otherwise, simply send this character. + // + else + { + // + // Wait until space is available in the UART transmit FIFO. + // + while(HWREG(UART0_BASE + UART_O_FR) & UART_FR_TXFF) + { + } + + // + // Send the char. + // + HWREG(UART0_BASE + UART_O_DR) = ui32Char & 0xff; + } +} +#endif + +//***************************************************************************** +// +// Sends a packet to the controller that is communicating with the boot loader. +// +//***************************************************************************** +static void +PacketWrite(uint32_t ui32Id, const uint8_t *pui8Data, uint32_t ui32Size) +{ + uint32_t ui32Idx; + +#ifdef CAN_UART_BRIDGE + // + // Check if the boot loader is in CAN mode. + // + if(g_ui32Interface == IFACE_CAN) + { +#endif + // + // Wait until the previous packet has been sent, providing a time out so + // that the boot loader does not hang here. + // + for(ui32Idx = 1000; + (ui32Idx != 0) && (CANRegRead(CAN0_BASE + CAN_O_TXRQ1) != 0); + ui32Idx--) + { + } + + // + // If the previous packet was sent, then send this packet. + // + if(ui32Idx != 0) + { + CANMessageSetTx(ui32Id, pui8Data, ui32Size); + } +#ifdef CAN_UART_BRIDGE + } + else + { + // + // The boot loader is in UART modes so write the packet using the UART + // functions. Write the start pattern followed by the size, and the ID. + // + UARTBridgeWrite(0xffffffff); + UARTBridgeWrite(ui32Size + 4); + UARTBridgeWrite(ui32Id & 0xff); + UARTBridgeWrite((ui32Id >> 8) & 0xff); + UARTBridgeWrite((ui32Id >> 16) & 0xff); + UARTBridgeWrite((ui32Id >> 24) & 0xff); + + // + // Now write out the remaining data bytes. + // + while(ui32Size--) + { + UARTBridgeWrite(*pui8Data++); + } + } +#endif +} + +//***************************************************************************** +// +//! This is the main routine for handling updating over CAN. +//! +//! This function accepts boot loader commands over CAN to perform a firmware +//! update over the CAN bus. This function assumes that the CAN bus timing +//! and message objects have been configured elsewhere. +//! +//! \return None. +// +//***************************************************************************** +void +UpdaterCAN(void) +{ + uint32_t ui32Bytes; + uint32_t ui32Cmd; + uint32_t ui32FlashSize; + uint32_t ui32Temp; + uint8_t ui8Status; + +#ifdef ENABLE_UPDATE_CHECK + // + // Check the application is valid and check the pin to see if an update is + // being requested. + // + if(g_ui32Forced == 1) + { + // + // Send out the CAN request. + // +#ifdef CAN_UART_BRIDGE + g_ui32Interface = IFACE_CAN; +#endif + PacketWrite(LM_API_UPD_REQUEST, 0, 0); + + // + // Send out the UART request. + // +#ifdef CAN_UART_BRIDGE + g_ui32Interface = IFACE_UART; + PacketWrite(LM_API_UPD_REQUEST, 0, 0); + g_ui32Interface = IFACE_UNKNOWN; +#endif + + // + // Wait only 50ms for the response and move on otherwise. + // + Delay(CRYSTAL_FREQ / 20); + + // + // Wait until a packet has been received. + // +#ifdef CAN_UART_BRIDGE + if((CANRegRead(CAN0_BASE + CAN_O_NWDA1) == 0) && + ((HWREG(UART0_BASE + UART_O_FR) & UART_FR_RXFE) == UART_FR_RXFE)) +#else + if(CANRegRead(CAN0_BASE + CAN_O_NWDA1) == 0) +#endif + { + // + // Call the application. + // + StartApplication(); + } + } +#endif + + // + // Loop forever processing packets. + // + while(1) + { + // + // Read the next packet. + // + ui32Bytes = 0; + ui32Cmd = PacketRead(g_pui8CommandBuffer, &ui32Bytes); + + // + // Handle this packet. + // + ui8Status = CAN_CMD_SUCCESS; + switch(ui32Cmd) + { + // + // This is an update request packet. + // + case LM_API_UPD_REQUEST: + { + // + // This packet is ignored (other than generating an ACK). + // + break; + } + + // + // This is a ping packet. + // + case LM_API_UPD_PING: + { + // + // This packet is ignored (other than generating an ACK). + // + break; + } + + // + // This is a reset packet. + // + case LM_API_UPD_RESET: + { + // + // Perform a software reset request. This will cause the + // microcontroller to reset; no further code will be executed. + // + HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | + NVIC_APINT_SYSRESETREQ); + + // + // The microcontroller should have reset, so this should never + // be reached. Just in case, loop forever. + // + while(1) + { + } + } + + // + // This is a data packet. + // + case LM_API_UPD_SEND_DATA: + { + // + // If this is overwriting the boot loader then the application + // has already been erased so now erase the boot loader. + // + if(g_ui32TransferAddress == 0) + { + // + // Clear the flash access interrupt. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // Erase the application before the boot loader. + // + for(ui32Temp = 0; ui32Temp < APP_START_ADDRESS; + ui32Temp += FLASH_PAGE_SIZE) + { + // + // Erase this block. + // + BL_FLASH_ERASE_FN_HOOK(ui32Temp); + } + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + // + // Setting g_ui32TransferSize to zero makes + // COMMAND_SEND_DATA fail to accept any more data. + // + g_ui32TransferSize = 0; + + // + // Indicate that the flash erase failed. + // + ui8Status = CAN_CMD_FAIL; + } + } + + // + // Check if there are any more bytes to receive. + // + if(g_ui32TransferSize >= ui32Bytes) + { + // + // Decrypt the data if required. + // +#ifdef BL_DECRYPT_FN_HOOK + BL_DECRYPT_FN_HOOK(g_pui8CommandBuffer, ui32Bytes); +#endif + + // + // Clear the flash access interrupt. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // Skip the first transfer. + // + if(g_ui32StartSize == g_ui32TransferSize) + { + g_ui32StartValues[0] = + *((uint32_t *)&g_pui8CommandBuffer[0]); + g_ui32StartValues[1] = + *((uint32_t *)&g_pui8CommandBuffer[4]); + } + else + { + // + // Loop over the words to program. + // + BL_FLASH_PROGRAM_FN_HOOK(g_ui32TransferAddress, + g_pui8CommandBuffer, + ui32Bytes); + } + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + // + // Indicate that the flash programming failed. + // + ui8Status = CAN_CMD_FAIL; + } + else + { + // + // Now update the address to program. + // + g_ui32TransferSize -= ui32Bytes; + g_ui32TransferAddress += ui32Bytes; + + // + // If a progress hook function has been provided, call + // it here. + // +#ifdef BL_PROGRESS_FN_HOOK + BL_PROGRESS_FN_HOOK(g_ui32StartSize - + g_ui32TransferSize, + g_ui32StartSize); +#endif + } + } + else + { + // + // This indicates that too much data is being sent to the + // device. + // + ui8Status = CAN_CMD_FAIL; + } + + // + // If the last expected bytes were received then write out the + // first two words of the image to allow it to boot. + // + if(g_ui32TransferSize == 0) + { + // + // Loop over the words to program. + // + BL_FLASH_PROGRAM_FN_HOOK(g_ui32StartAddress, + (uint8_t *)&g_ui32StartValues, + 8); + + // + // If an end signal hook function has been provided, call + // it here since we have finished a download. + // +#ifdef BL_END_FN_HOOK + BL_END_FN_HOOK(); +#endif + } + break; + } + + // + // This is a start download packet. + // + case LM_API_UPD_DOWNLOAD: + { + // + // Get the application address and size from the packet data. + // + g_ui32TransferAddress = + *((uint32_t *)&g_pui8CommandBuffer[0]); + g_ui32TransferSize = *((uint32_t *)&g_pui8CommandBuffer[4]); + g_ui32StartSize = g_ui32TransferSize; + g_ui32StartAddress = g_ui32TransferAddress; + + // + // Check for a valid starting address and image size. + // + if(!BL_FLASH_AD_CHECK_FN_HOOK(g_ui32TransferAddress, + g_ui32TransferSize)) + { + // + // Set the code to an error to indicate that the last + // command failed. This informs the updater program + // that the download command failed. + // + ui8Status = CAN_CMD_FAIL; + + // + // This packet has been handled. + // + break; + } + + // + // Only erase the space that we need if we are not protecting + // the code, otherwise erase the entire flash. + // +#ifdef FLASH_CODE_PROTECTION + ui32FlashSize = BL_FLASH_SIZE_FN_HOOK(); +#ifdef FLASH_RSVD_SPACE + if((ui32FlashSize - FLASH_RSVD_SPACE) != g_ui32TransferAddress) + { + ui32FlashSize -= FLASH_RSVD_SPACE; + } +#endif +#else + ui32FlashSize = g_ui32TransferAddress + g_ui32TransferSize; +#endif + + // + // Clear the flash access interrupt. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // Leave the boot loader present until we start getting an + // image. + // + for(ui32Temp = g_ui32TransferAddress; ui32Temp < ui32FlashSize; + ui32Temp += FLASH_PAGE_SIZE) + { + // + // Erase this block. + // + BL_FLASH_ERASE_FN_HOOK(ui32Temp); + } + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + ui8Status = CAN_CMD_FAIL; + } + + // + // See if the command was successful. + // + if(ui8Status != CAN_CMD_SUCCESS) + { + // + // Setting g_ui32TransferSize to zero makes + // COMMAND_SEND_DATA fail to accept any data. + // + g_ui32TransferSize = 0; + } +#ifdef BL_START_FN_HOOK + else + { + // + // If a start signal hook function has been provided, call + // it here since we are about to start a new download. + // + BL_START_FN_HOOK(); + } +#endif + + break; + } + + // + // This is an unknown packet. + // + default: + { + // + // Set the status to indicate a failure. + // + ui8Status = CAN_CMD_FAIL; + break; + } + } + + // + // Send an ACK packet in response to indicate that the packet was + // received. The status in the ACK data indicates if the command was + // successfully processed. + // + PacketWrite(LM_API_UPD_ACK, &ui8Status, 1); + } +} + +//***************************************************************************** +// +// Configures the UART used for CAN traffic bridging. +// +//***************************************************************************** +#ifdef CAN_UART_BRIDGE +void +ConfigureBridge(void) +{ + // + // Enable the GPIO module if necessary. + // +#if (CAN_RX_PERIPH != SYSCTL_RCGCGPIO_R0) && \ + (CAN_TX_PERIPH != SYSCTL_RCGCGPIO_R0) + HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0; +#endif + + // + // Enable the UART module. + // + HWREG(SYSCTL_RCGCUART) |= SYSCTL_RCGCUART_R0; + + // + // Enable the GPIO pins used for the UART. + // + HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_PINS; + HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) |= UART_PINS_PCTL; + HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_PINS; + + // + // Configure the UART. + // + HWREG(UART0_BASE + UART_O_IBRD) = UART_BAUD_RATIO(115200) >> 6; + HWREG(UART0_BASE + UART_O_FBRD) = (UART_BAUD_RATIO(115200) & + UART_FBRD_DIVFRAC_M); + HWREG(UART0_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; + HWREG(UART0_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); +} +#endif + +//***************************************************************************** +// +//! This is the application entry point to the CAN updater. +//! +//! This function should only be entered from a running application and not +//! when running the boot loader with no application present. +//! +//! \return None. +// +//***************************************************************************** +void +AppUpdaterCAN(void) +{ + // + // If the boot loader is being called from the application the UART needs + // to be configured. + // +#ifdef CAN_UART_BRIDGE + ConfigureBridge(); +#endif + + // + // Configure the CAN controller but don't change the bit timing. + // + ConfigureCANInterface(0); + + // + // Call the main update routine. + // + UpdaterCAN(); +} + +//***************************************************************************** +// +//! Generic configuration is handled in this function. +//! +//! This function is called by the start up code to perform any configuration +//! necessary before calling the update routine. +//! +//! \return None. +// +//***************************************************************************** +void +ConfigureCAN(void) +{ +#ifdef CRYSTAL_FREQ +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. Check for whether the Oscillator range + // has to be set and wait states need to be updated + // + if(CRYSTAL_FREQ >= 10000000) + { + HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG); + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | SYSCTL_MOSCCTL_NOXTAL); + } + else + { + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | SYSCTL_MOSCCTL_NOXTAL); + } + + // + // Wait for the Oscillator to Stabilize + // + Delay(524288); + + if(CRYSTAL_FREQ > 16000000) + { + HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 | (1 << SYSCTL_MEMTIM0_FWS_S) | + SYSCTL_MEMTIM0_EBCHT_1_5 | (1 << SYSCTL_MEMTIM0_EWS_S) | + SYSCTL_MEMTIM0_MB1); + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_MEMTIMU | SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } + else + { + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } +#else + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. + // + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS); + + // + // Delay while the main oscillator starts up. + // + Delay(524288); + + // + // Set the crystal frequency and switch to the main oscillator. + // + HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & + ~(SYSCTL_RCC_XTAL_M | SYSCTL_RCC_OSCSRC_M)) | + XTAL_VALUE | SYSCTL_RCC_OSCSRC_MAIN); +#endif +#endif + + // + // Enable the CAN controller. + // + HWREG(SYSCTL_RCGCCAN) |= SYSCTL_RCGCCAN_R0; + +#if CAN_RX_PERIPH == CAN_TX_PERIPH + // + // Enable the GPIO associated with CAN0 + // + HWREG(SYSCTL_RCGCGPIO) |= CAN_RX_PERIPH; + + // + // Wait a while before accessing the peripheral. + // + Delay(3); + + // + // Set the alternate function selects. + // + HWREG(CAN_RX_PORT + GPIO_O_AFSEL) |= CAN_RX_PIN_M | CAN_TX_PIN_M; + + // + // Set the port control selects. + // + HWREG(CAN_RX_PORT + GPIO_O_PCTL) |= CAN_RX_PIN_PCTL_M | CAN_TX_PIN_PCTL_M; + + // + // Set the pin type to it's digital function. + // + HWREG(CAN_RX_PORT + GPIO_O_DEN) |= CAN_RX_PIN_M | CAN_TX_PIN_M; + +#else + // + // Enable the GPIO associated with CAN0 + // + HWREG(SYSCTL_RCGCGPIO) |= CAN_RX_PERIPH | CAN_TX_PERIPH; + + // + // Wait a while before accessing the peripheral. + // + Delay(3); + + // + // Set the alternate function selects. + // + HWREG(CAN_RX_PORT + GPIO_O_AFSEL) |= CAN_RX_PIN_M; + HWREG(CAN_TX_PORT + GPIO_O_AFSEL) |= CAN_TX_PIN_M; + + // + // Set the port control selects. + // + HWREG(CAN_RX_PORT + GPIO_O_PCTL) |= CAN_RX_PIN_PCTL_M; + HWREG(CAN_TX_PORT + GPIO_O_PCTL) |= CAN_TX_PIN_PCTL_M; + + // + // Set the pin type to it's digital function. + // + HWREG(CAN_RX_PORT + GPIO_O_DEN) |= CAN_RX_PIN_M; + HWREG(CAN_TX_PORT + GPIO_O_DEN) |= CAN_TX_PIN_M; +#endif + + // + // Configure the UART used for bridging. + // +#ifdef CAN_UART_BRIDGE + ConfigureBridge(); +#endif + + // + // Configure the CAN interface. + // + ConfigureCANInterface(1); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.h new file mode 100644 index 0000000000000000000000000000000000000000..c8e4f34ac1e366d5e808040f6a0d8618164f4b65 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can.h @@ -0,0 +1,64 @@ +//***************************************************************************** +// +// bl_can.h - Definitions for the CAN transport functions. +// +// Copyright (c) 2008-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CAN_H__ +#define __BL_CAN_H__ + +//***************************************************************************** +// +// These defines are used to define the range of values that are used for +// the CAN update protocol. +// +//***************************************************************************** +#define CAN_MSGID_DTYPE_UPDATE 0x1f000000 +#define CAN_MSGID_MFR_LM 0x00020000 + +//***************************************************************************** +// +// The masks of the fields that are used in the message identifier. +// +//***************************************************************************** +#define CAN_MSGID_DEVNO_M 0x0000003f +#define CAN_MSGID_API_M 0x0000ffc0 +#define CAN_MSGID_MFR_M 0x00ff0000 +#define CAN_MSGID_DTYPE_M 0x1f000000 +#define CAN_MSGID_DEVNO_S 0 +#define CAN_MSGID_API_S 6 +#define CAN_MSGID_MFR_S 16 +#define CAN_MSGID_DTYPE_S 24 + +//***************************************************************************** +// +// Firmware Update API definitions. +// +//***************************************************************************** +#define LM_API_UPD (CAN_MSGID_MFR_LM | CAN_MSGID_DTYPE_UPDATE) +#define LM_API_UPD_PING (LM_API_UPD | (0 << CAN_MSGID_API_S)) +#define LM_API_UPD_DOWNLOAD (LM_API_UPD | (1 << CAN_MSGID_API_S)) +#define LM_API_UPD_SEND_DATA (LM_API_UPD | (2 << CAN_MSGID_API_S)) +#define LM_API_UPD_RESET (LM_API_UPD | (3 << CAN_MSGID_API_S)) +#define LM_API_UPD_ACK (LM_API_UPD | (4 << CAN_MSGID_API_S)) +#define LM_API_UPD_REQUEST (LM_API_UPD | (6 << CAN_MSGID_API_S)) + +#endif // __BL_CAN_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can_timing.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can_timing.h new file mode 100644 index 0000000000000000000000000000000000000000..742dd0da21d86e9e191d2328d2408f9b3c63bf25 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_can_timing.h @@ -0,0 +1,241 @@ +//***************************************************************************** +// +// bl_can_timing.h - Timing definitions for the CAN controller. +// +// Copyright (c) 2008-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CAN_TIMING_H__ +#define __BL_CAN_TIMING_H__ + +#ifdef CAN_ENABLE_UPDATE + +//***************************************************************************** +// +// This macro is used to generate the proper value for CAN_BIT_TIMING. The +// values selected for each crystal/bit rate combination assumes a propagation +// delay of 300ns (which will always be rounded up to the next integer multiple +// of the CAN time quanta). +// +//***************************************************************************** +#define CAN_BIT_REG(seg1, seg2, sjw, brp) \ + ((((seg2 - 1) << CAN_BIT_TSEG2_S) & \ + CAN_BIT_TSEG2_M) | \ + (((seg1 - 1) << CAN_BIT_TSEG1_S) & \ + CAN_BIT_TSEG1_M) | \ + (((sjw - 1) << CAN_BIT_SJW_S) & \ + CAN_BIT_SJW_M) | \ + (((brp - 1) << CAN_BIT_BRP_S) & \ + CAN_BIT_BRP_M)) + +//***************************************************************************** +// +// The settings for a 16MHz crystal frequency. +// +//***************************************************************************** +#if CRYSTAL_FREQ == 16000000 +#if CAN_BIT_RATE == 1000000 +#define CAN_BIT_TIMING CAN_BIT_REG(10, 5, 4, 1) // tProp = 312ns +#elif CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(9, 6, 4, 2) // tProp = 375ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(4, 3, 3, 8) // tProp = 500ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 8) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 20) // tProp = 1250ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 50) // tProp = 3125ns +#else +#error Invalid CAN_BIT_RATE value used with a 16MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 12MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 12000000 +#if CAN_BIT_RATE == 1000000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 3, 3, 1) // tProp = 416ns +#elif CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(7, 4, 4, 2) // tProp = 500ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 5, 4, 4) // tProp = 333ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 6) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 15) // tProp = 1250ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 5, 4, 50) // tProp = 4166ns +#else +#error Invalid CAN_BIT_RATE value used with a 12MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 10MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 10000000 +#if CAN_BIT_RATE == 1000000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 3, 3, 1) // tProp = 300ns +#elif CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(11, 8, 4, 1) // tProp = 300ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 4) // tProp = 400ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 5) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 20) // tProp = 2000ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 50) // tProp = 5000ns +#else +#error Invalid CAN_BIT_RATE value used with a 10MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 8MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 8000000 +#if CAN_BIT_RATE == 1000000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 2, 2, 1) // tProp = 375ns +#elif CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(9, 6, 4, 1) // tProp = 375ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(4, 3, 3, 4) // tProp = 500ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 4) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 10) // tProp = 1250ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 25) // tProp = 3125ns +#else +#error Invalid CAN_BIT_RATE value used with a 8MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 6MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 6000000 +#if CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(7, 4, 4, 1) // tProp = 500ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 5, 4, 2) // tProp = 333ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 3) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 5, 4, 10) // tProp = 1666ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 5, 4, 25) // tProp = 4166ns +#else +#error Invalid CAN_BIT_RATE value used with a 6MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 5MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 5000000 +#if CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(6, 3, 3, 1) // tProp = 600ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 2) // tProp = 400ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 4) // tProp = 800ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 10) // tProp = 2000ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 25) // tProp = 5000ns +#else +#error Invalid CAN_BIT_RATE value used with a 5MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 4MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 4000000 +#if CAN_BIT_RATE == 500000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 2, 2, 1) // tProp = 750ns +#elif CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(4, 3, 3, 2) // tProp = 500ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 2) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 5) // tProp = 1250ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 20) // tProp = 5000ns +#else +#error Invalid CAN_BIT_RATE value used with a 4MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 2MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 2000000 +#if CAN_BIT_RATE == 250000 +#define CAN_BIT_TIMING CAN_BIT_REG(4, 3, 3, 1) // tProp = 500ns +#elif CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(8, 7, 4, 1) // tProp = 500ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 4) // tProp = 2000ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 10) // tProp = 5000ns +#else +#error Invalid CAN_BIT_RATE value used with a 2MHz crystal. +#endif + +//***************************************************************************** +// +// The settings for a 1MHz crystal frequency. +// +//***************************************************************************** +#elif CRYSTAL_FREQ == 1000000 +#if CAN_BIT_RATE == 125000 +#define CAN_BIT_TIMING CAN_BIT_REG(4, 3, 3, 1) // tProp = 1000ns +#elif CAN_BIT_RATE == 50000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 2) // tProp = 2000ns +#elif CAN_BIT_RATE == 20000 +#define CAN_BIT_TIMING CAN_BIT_REG(5, 4, 4, 5) // tProp = 5000ns +#else +#error Invalid CAN_BIT_RATE value used with a 1MHz crystal. +#endif + +//***************************************************************************** +// +// An unsupported crystal frequency was specified. +// +//***************************************************************************** +#else +#error The CRYSTAL_FREQ value is not supported by the CAN controller. +#endif + +#endif + +#endif // __BL_CAN_TIMING_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.c new file mode 100644 index 0000000000000000000000000000000000000000..30187fc28c83dec1ee2f82a13927adac60fd11b6 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.c @@ -0,0 +1,266 @@ +//***************************************************************************** +// +// bl_check.c - Code to check for a forced update. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "bl_config.h" +#include "boot_loader/bl_check.h" +#include "boot_loader/bl_hooks.h" +#ifdef CHECK_CRC +#include "boot_loader/bl_crc32.h" +#endif + +//***************************************************************************** +// +//! \addtogroup bl_check_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// This global is used to remember if a forced update occurred. +// +//***************************************************************************** +#ifdef ENABLE_UPDATE_CHECK +uint32_t g_ui32Forced; +#endif + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for a predictable length +// delay. +// +//***************************************************************************** +extern void Delay(uint32_t ui32Count); + +//***************************************************************************** +// +//! Checks a GPIO for a forced update. +//! +//! This function checks the state of a GPIO to determine if a update is being +//! requested. +//! +//! \return Returns a non-zero value if an update is being requested and zero +//! otherwise. +// +//***************************************************************************** +#ifdef ENABLE_UPDATE_CHECK +uint32_t +CheckGPIOForceUpdate(void) +{ + // + // Enable the required GPIO module. + // + HWREG(SYSCTL_RCGCGPIO) |= FORCED_UPDATE_PERIPH; + + // + // Wait a while before accessing the peripheral. + // + Delay(3); + +#ifdef FORCED_UPDATE_KEY + // + // Unlock the GPIO Access. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_LOCK) = FORCED_UPDATE_KEY; + HWREG(FORCED_UPDATE_PORT + GPIO_O_CR) = 1 << FORCED_UPDATE_PIN; +#endif + + // + // Enable the pin used to see if an update is being requested. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_DEN) |= 1 << FORCED_UPDATE_PIN; +#ifdef FORCED_UPDATE_WPU + // + // Set the output drive strength. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_DR2R) |= 1 << FORCED_UPDATE_PIN; + + // + // Enable the weak pull up. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_PUR) |= 1 << FORCED_UPDATE_PIN; + + // + // Make sure that the analog mode select register is clear for this pin. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_AMSEL) &= ~(1 << FORCED_UPDATE_PIN); +#endif +#ifdef FORCED_UPDATE_WPD + // + // Set the output drive strength. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_DR2R) |= 1 << FORCED_UPDATE_PIN; + + // + // Enable the weak pull down. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_PDR) |= 1 << FORCED_UPDATE_PIN; + + // + // Make sure that the analog mode select register is clear for this pin. + // This register only appears in DustDevil-class (and later) devices, but + // is a harmless write on Sandstorm- and Fury-class devices. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_AMSEL) &= ~(1 << FORCED_UPDATE_PIN); +#endif + +#ifdef FORCED_UPDATE_KEY + // + // Unlock the GPIO Access. + // + HWREG(FORCED_UPDATE_PORT + GPIO_O_LOCK) = FORCED_UPDATE_KEY; + HWREG(FORCED_UPDATE_PORT + GPIO_O_CR) = 0; +#endif + + // + // Wait a while before reading the pin. + // + Delay(1000); + + // + // Check the pin to see if an update is being requested. + // + if(HWREG(FORCED_UPDATE_PORT + (1 << (FORCED_UPDATE_PIN + 2))) == + (FORCED_UPDATE_POLARITY << FORCED_UPDATE_PIN)) + { + // + // Remember that this was a forced update. + // + g_ui32Forced = 1; + + return(1); + } + + // + // No update is being requested so return 0. + // + return(0); +} +#endif + +//***************************************************************************** +// +//! Checks if an update is needed or is being requested. +//! +//! This function detects if an update is being requested or if there is no +//! valid code presently located on the microcontroller. This is used to tell +//! whether or not to enter update mode. +//! +//! \return Returns a non-zero value if an update is needed or is being +//! requested and zero otherwise. +// +//***************************************************************************** +uint32_t +CheckForceUpdate(void) +{ +#ifdef CHECK_CRC + uint32_t ui32Retcode; +#endif + +#ifdef BL_CHECK_UPDATE_FN_HOOK + // + // If the update check function is hooked, call the application to determine + // how to proceed. + // + return(BL_CHECK_UPDATE_FN_HOOK()); +#else + uint32_t *pui32App; + +#ifdef ENABLE_UPDATE_CHECK + g_ui32Forced = 0; +#endif + + // + // See if the first location is 0xfffffffff or something that does not + // look like a stack pointer, or if the second location is 0xffffffff or + // something that does not look like a reset vector. + // + pui32App = (uint32_t *)APP_START_ADDRESS; + if((pui32App[0] == 0xffffffff) || + ((pui32App[0] & 0xfff00000) != 0x20000000) || + (pui32App[1] == 0xffffffff) || + ((pui32App[1] & 0xfff00001) != 0x00000001)) + { + return(1); + } + + // + // If required, scan the image for an embedded CRC and ensure that it + // matches the current CRC of the image. + // +#ifdef CHECK_CRC + InitCRC32Table(); + ui32Retcode = CheckImageCRC32(pui32App); + + // + // If ENFORCE_CRC is defined, we only boot the image if the CRC is + // present in the image information header and the value calculated + // matches the value in the header. If ENFORCE_CRC is not defined, we + // the image if the CRC is good but also if the length field of the header + // is zero (which typically indicates that the post-build step of running + // binpack to add the length and CRC to the header was not run). + // +#ifdef ENFORCE_CRC + if(ui32Retcode != CHECK_CRC_OK) +#else + if((ui32Retcode != CHECK_CRC_OK) && (ui32Retcode != CHECK_CRC_NO_LENGTH)) +#endif + { + // + // The CRC32 image check failed indicating that the image is + // corrupt (or doesn't have the CRC embedded correctly). Either way, + // fail the update check and force the boot loader to retain control. + // + return(2); + } +#endif + +#ifdef ENABLE_UPDATE_CHECK + // + // If simple GPIO checking is configured, determine whether or not to force + // an update. + // + return(CheckGPIOForceUpdate()); +#else + // + // GPIO checking is not required so, if we get here, a valid image exists + // and no update is needed. + // + return(0); +#endif +#endif +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.h new file mode 100644 index 0000000000000000000000000000000000000000..1c621f2ce23847f86e15f69cef3ef710cbaedbd4 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_check.h @@ -0,0 +1,39 @@ +//***************************************************************************** +// +// bl_check.h - Definitions for the forced update check function. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CHECK_H__ +#define __BL_CHECK_H__ + +//***************************************************************************** +// +// Prototype for the forced update check function. +// +//***************************************************************************** +extern uint32_t CheckForceUpdate(void); +#ifdef ENABLE_UPDATE_CHECK +extern uint32_t CheckGPIOForceUpdate(void); +extern uint32_t g_ui32Forced; +#endif + +#endif // __BL_CHECK_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_commands.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_commands.h new file mode 100644 index 0000000000000000000000000000000000000000..f2ad7a727455e37d106a6447ca2c0197a05a90a9 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_commands.h @@ -0,0 +1,242 @@ +//***************************************************************************** +// +// bl_commands.h - The list of commands and return messages supported by the +// boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_COMMANDS_H__ +#define __BL_COMMANDS_H__ + +//***************************************************************************** +// +// This command is used to receive an acknowledge from the the boot loader +// proving that communication has been established. This command is a single +// byte. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_PING; +// +//***************************************************************************** +#define COMMAND_PING 0x20 + +//***************************************************************************** +// +// This command is sent to the boot loader to indicate where to store data and +// how many bytes will be sent by the COMMAND_SEND_DATA commands that follow. +// The command consists of two 32-bit values that are both transferred MSB +// first. The first 32-bit value is the address to start programming data +// into, while the second is the 32-bit size of the data that will be sent. +// This command also triggers an erasure of the full application area in the +// flash or possibly the entire flash depending on the address used. This +// causes the command to take longer to send the ACK/NAK in response to the +// command. This command should be followed by a COMMAND_GET_STATUS to ensure +// that the program address and program size were valid for the microcontroller +// running the boot loader. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0] = COMMAND_DOWNLOAD; +// ui8Command[1] = Program Address [31:24]; +// ui8Command[2] = Program Address [23:16]; +// ui8Command[3] = Program Address [15:8]; +// ui8Command[4] = Program Address [7:0]; +// ui8Command[5] = Program Size [31:24]; +// ui8Command[6] = Program Size [23:16]; +// ui8Command[7] = Program Size [15:8]; +// ui8Command[8] = Program Size [7:0]; +// +//***************************************************************************** +#define COMMAND_DOWNLOAD 0x21 + +//***************************************************************************** +// +// This command is sent to the boot loader to transfer execution control to the +// specified address. The command is followed by a 32-bit value, transferred +// MSB first, that is the address to which execution control is transferred. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[5]; +// +// ui8Command[0] = COMMAND_RUN; +// ui8Command[1] = Run Address [31:24]; +// ui8Command[2] = Run Address [23:16]; +// ui8Command[3] = Run Address [15:8]; +// ui8Command[4] = Run Address [7:0]; +// +//***************************************************************************** +#define COMMAND_RUN 0x22 + +//***************************************************************************** +// +// This command returns the status of the last command that was issued. +// Typically this command should be received after every command is sent to +// ensure that the previous command was successful or, if unsuccessful, to +// properly respond to a failure. The command requires one byte in the data of +// the packet and the boot loader should respond by sending a packet with one +// byte of data that contains the current status code. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_GET_STATUS; +// +// The following are the definitions for the possible status values that can be +// returned from the boot loader when COMMAND_GET_STATUS is sent to +// the microcontroller. +// +// COMMAND_RET_SUCCESS +// COMMAND_RET_UNKNOWN_CMD +// COMMAND_RET_INVALID_CMD +// COMMAND_RET_INVALID_ADD +// COMMAND_RET_FLASH_FAIL +// COMMAND_RET_CRC_FAIL +// +//***************************************************************************** +#define COMMAND_GET_STATUS 0x23 + +//***************************************************************************** +// +// This command should only follow a COMMAND_DOWNLOAD command or another +// COMMAND_SEND_DATA command, if more data is needed. Consecutive send data +// commands automatically increment the address and continue programming from +// the previous location. The transfer size is limited by the size of the +// receive buffer in the boot loader (as configured by the BUFFER_SIZE +// parameter). The command terminates programming once the number of bytes +// indicated by the COMMAND_DOWNLOAD command has been received. Each time this +// function is called, it should be followed by a COMMAND_GET_STATUS command to +// ensure that the data was successfully programmed into the flash. If the +// boot loader sends a NAK to this command, the boot loader will not increment +// the current address to allow retransmission of the previous data. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[9]; +// +// ui8Command[0] = COMMAND_SEND_DATA; +// ui8Command[1] = Data[0]; +// ui8Command[2] = Data[1]; +// ui8Command[3] = Data[2]; +// ui8Command[4] = Data[3]; +// ui8Command[5] = Data[4]; +// ui8Command[6] = Data[5]; +// ui8Command[7] = Data[6]; +// ui8Command[8] = Data[7]; +// +//***************************************************************************** +#define COMMAND_SEND_DATA 0x24 + +//***************************************************************************** +// +// This command is used to tell the boot loader to reset. This is used after +// downloading a new image to the microcontroller to cause the new application +// or the new boot loader to start from a reset. The normal boot sequence +// occurs and the image runs as if from a hardware reset. It can also be used +// to reset the boot loader if a critical error occurs and the host device +// wants to restart communication with the boot loader. +// +// The format of the command is as follows: +// +// uint8_t ui8Command[1]; +// +// ui8Command[0] = COMMAND_RESET; +// +// The boot loader responds with an ACK signal to the host device before +// actually executing the software reset on the microcontroller running the +// boot loader. This informs the updater application that the command was +// received successfully and the part will be reset. +// +//***************************************************************************** +#define COMMAND_RESET 0x25 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous command completed successful. +// +//***************************************************************************** +#define COMMAND_RET_SUCCESS 0x40 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the command sent was an unknown command. +// +//***************************************************************************** +#define COMMAND_RET_UNKNOWN_CMD 0x41 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous command was formatted incorrectly. +// +//***************************************************************************** +#define COMMAND_RET_INVALID_CMD 0x42 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the previous download command contained an invalid address value. +// +//***************************************************************************** +#define COMMAND_RET_INVALID_ADR 0x43 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that an attempt to program or erase the flash has failed. +// +//***************************************************************************** +#define COMMAND_RET_FLASH_FAIL 0x44 + +//***************************************************************************** +// +// This is returned in response to a COMMAND_GET_STATUS command and indicates +// that the boot loader is configured to check the embedded CRC32 in the +// downloaded image but the check failed. This status can only be returned +// after the last COMMAND_SEND_DATA has been received and processed, and only +// if CHECK_CRC is defined in the boot loader configuration. +// +//***************************************************************************** +#define COMMAND_RET_CRC_FAIL 0x45 + +//***************************************************************************** +// +// This is the value that is sent to acknowledge a packet. +// +//***************************************************************************** +#define COMMAND_ACK 0xcc + +//***************************************************************************** +// +// This is the value that is sent to not-acknowledge a packet. +// +//***************************************************************************** +#define COMMAND_NAK 0x33 + +#endif // __BL_COMMANDS_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.c new file mode 100644 index 0000000000000000000000000000000000000000..ff0af0f086d8ee6c1aafe8011699a319f8e71549 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.c @@ -0,0 +1,164 @@ +//***************************************************************************** +// +// bl_config.c - A dummy C file to generate bl_config.in from bl_config.h. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include "bl_config.h" + +//***************************************************************************** +// +// Since the RV-MDK assembler is not able to run assembly code through the C +// preprocessor, the relevant contents of bl_config.h need to be converted to +// assembly format for inclusion into the RV-MDK startup code. This file +// performs this conversion when manually run through the C preprocessor via: +// +// armcc --device DLM -o bl_config.inc -E bl_config.c +// +// This file does not contain valid C code and will fail to compile (-E tells +// the compiler to preprocess but not attempt to compile the code). +// +//***************************************************************************** + +//***************************************************************************** +// +// Define an assembler symbol for the stack size. +// +//***************************************************************************** +_STACK_SIZE equ STACK_SIZE + +//***************************************************************************** +// +// Define an assembler symbol for the application starting address. +// +//***************************************************************************** +_APP_START_ADDRESS equ APP_START_ADDRESS + +//***************************************************************************** +// +// Define an assembler symbol for the application vector table address. +// +//***************************************************************************** +_VTABLE_START_ADDRESS equ VTABLE_START_ADDRESS + +//***************************************************************************** +// +// Define an assembler symbol if the MOSCFAIL handler is enabled. +// +//***************************************************************************** +#ifdef ENABLE_MOSCFAIL_HANDLER +_ENABLE_MOSCFAIL_HANDLER equ 1 +#endif + +//***************************************************************************** +// +// Define an assembler symbol if update via the UART is enabled. +// +//***************************************************************************** +#ifdef UART_ENABLE_UPDATE +_UART_ENABLE_UPDATE equ 1 +#endif + +//***************************************************************************** +// +// Define an assember symbol if UART autobauding is enabled. +// +//***************************************************************************** +#ifdef UART_AUTOBAUD +_UART_AUTOBAUD equ 1 +#endif + +//***************************************************************************** +// +// Define an assembler symbol if update via Ethernet is enabled. +// +//***************************************************************************** +#ifdef ENET_ENABLE_UPDATE +_ENET_ENABLE_UPDATE equ 1 +#endif + +//***************************************************************************** +// +// Define an assembler symbol if update via CAN is enabled. +// +//***************************************************************************** +#ifdef CAN_ENABLE_UPDATE +_CAN_ENABLE_UPDATE equ 1 +#endif + +//***************************************************************************** +// +// Define an assembler symbol if update via USB is enabled. +// +//***************************************************************************** +#ifdef USB_ENABLE_UPDATE +_USB_ENABLE_UPDATE equ 1 +#endif + +//***************************************************************************** +// +// Define an assembler symbol if a hardware initialization hook is provided. +// +//***************************************************************************** +#ifdef BL_HW_INIT_FN_HOOK +#define _quote(x) #x +#define quote(x) _quote(x) + gbls _BL_HW_INIT_FN_HOOK +_BL_HW_INIT_FN_HOOK sets quote(BL_HW_INIT_FN_HOOK) +#undef _quote +#undef quote +#endif + +//***************************************************************************** +// +// Define an assembler symbol if an initialization hook is provided. +// +//***************************************************************************** +#ifdef BL_INIT_FN_HOOK +#define _quote(x) #x +#define quote(x) _quote(x) + gbls _BL_INIT_FN_HOOK +_BL_INIT_FN_HOOK sets quote(BL_INIT_FN_HOOK) +#undef _quote +#undef quote +#endif + +//***************************************************************************** +// +// Define an assembler symbol if a re-initialization hook is provided. +// +//***************************************************************************** +#ifdef BL_REINIT_FN_HOOK +#define _quote(x) #x +#define quote(x) _quote(x) + gbls _BL_REINIT_FN_HOOK +_BL_REINIT_FN_HOOK sets quote(BL_REINIT_FN_HOOK) +#undef _quote +#undef quote +#endif + +//***************************************************************************** +// +// The assembler will require an end statement at the end of the output +// bl_config.inc file. +// +//***************************************************************************** + end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.h.tmpl b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.h.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..f5e17f5ab4f36eeeb9b688d3f7ad5cf18a41f0c3 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_config.h.tmpl @@ -0,0 +1,1578 @@ +//***************************************************************************** +// +// bl_config.h - The configurable parameters of the boot loader. +// +// Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CONFIG_H__ +#define __BL_CONFIG_H__ + +//***************************************************************************** +// +// The following defines are used to configure the operation of the boot +// loader. For each define, its interactions with other defines are described. +// First is the dependencies (i.e. the defines that must also be defined if it +// is defined), next are the exclusives (i.e. the defines that can not be +// defined if it is defined), and finally are the requirements (i.e. the +// defines that must be defined if it is defined). +// +// The following defines must be defined in order for the boot loader to +// operate: +// +// One of CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE, +// SSI_ENABLE_UPDATE, UART_ENABLE_UPDATE, or USB_ENABLE_UPDATE +// APP_START_ADDRESS +// STACK_SIZE +// BUFFER_SIZE +// +//***************************************************************************** + +//***************************************************************************** +// +// The frequency of the crystal used to clock the microcontroller. +// +// This defines the crystal frequency used by the microcontroller running the +// boot loader. If this is unknown at the time of production, then use the +// UART_AUTOBAUD feature to properly configure the UART. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define CRYSTAL_FREQ 8000000 + +//***************************************************************************** +// +// This enables the boosting of the LDO voltage to 2.75V. For boot loader +// configurations that enable the PLL (for example, using the Ethernet port) +// on a part that has the PLL errata, this should be enabled. This applies to +// revision A2 of Fury-class devices. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define BOOST_LDO_VOLTAGE + +//***************************************************************************** +// +// The starting address of the application. This must be a multiple of 1024 +// bytes (making it aligned to a page boundary). A vector table is expected at +// this location, and the perceived validity of the vector table (stack located +// in SRAM, reset vector located in flash) is used as an indication of the +// validity of the application image. +// +// The flash image of the boot loader must not be larger than this value. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define APP_START_ADDRESS 0x00001000 + +//***************************************************************************** +// +// The address at which the application locates its exception vector table. +// This must be a multiple of 1KB (making it aligned to a page boundary). +// Typically, an application will start with its vector table and this value +// will default to APP_START_ADDRESS. This option is provided to cater for +// applications which run from external memory which may not be accessible by +// the NVIC (the vector table offset register is only 30 bits long). +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define VTABLE_START_ADDRESS 0x00001000 + +//***************************************************************************** +// +// The size of a single, erasable page in the flash. This must be a power +// of 2. The default value of 1KB represents the page size for the internal +// flash on all Tiva MCUs and this value should only be overridden if +// configuring a boot loader to access external flash devices with a page size +// different from this. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define FLASH_PAGE_SIZE 0x00000400 + +//***************************************************************************** +// +// The amount of space at the end of flash to reserved. This must be a +// multiple of 1024 bytes (making it aligned to a page boundary). This +// reserved space is not erased when the application is updated, providing +// non-volatile storage that can be used for parameters. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define FLASH_RSVD_SPACE 0x00000800 + +//***************************************************************************** +// +// The number of words of stack space to reserve for the boot loader. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define STACK_SIZE 64 + +//***************************************************************************** +// +// The number of words in the data buffer used for receiving packets. This +// value must be at least 3. If using autobauding on the UART, this must be at +// least 20. The maximum usable value is 65 (larger values will result in +// unused space in the buffer). +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +#define BUFFER_SIZE 20 + +//***************************************************************************** +// +// Enables updates to the boot loader. Updating the boot loader is an unsafe +// operation since it is not fully fault tolerant (losing power to the device +// part way though could result in the boot loader no longer being present in +// flash). +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENABLE_BL_UPDATE + +//***************************************************************************** +// +// This definition will cause the the boot loader to erase the entire flash on +// updates to the boot loader or to erase the entire application area when the +// application is updated. This erases any unused sections in the flash before +// the firmware is updated. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define FLASH_CODE_PROTECTION + +//***************************************************************************** +// +// Enables the call to decrypt the downloaded data before writing it into +// flash. The decryption routine is empty in the reference boot loader source, +// which simply provides a placeholder for adding an actual decrypter. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENABLE_DECRYPTION + +//***************************************************************************** +// +// Enables support for the MOSCFAIL handler in the NMI interrupt. +// Note: Sandstorm or Fury devices do not provide the MOSCFAIL reset, so this +// feature should not be enabled for these devices. +// +// Depends on: None +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENABLE_MOSCFAIL_HANDLER + +//***************************************************************************** +// +// Enables the pin-based forced update check. When enabled, the boot loader +// will go into update mode instead of calling the application if a pin is read +// at a particular polarity, forcing an update operation. In either case, the +// application is still able to return control to the boot loader in order to +// start an update. +// +// Depends on: None +// Exclusive of: None +// Requires: FORCED_UPDATE_PERIPH, FORCED_UPDATE_PORT, FORCED_UPDATE_PIN, +// FORCED_UPDATE_POLARITY +// +//***************************************************************************** +//#define ENABLE_UPDATE_CHECK + +//***************************************************************************** +// +// The GPIO module to enable in order to check for a forced update. This will +// be one of the SYSCTL_RCGCGPIO_Rx values, where Rx represnts the required +// GPIO port. This applies to Blizzard class and later devices for FORCED_UPDATE_PORT. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_PERIPH SYSCTL_RCGCGPIO_R1 + +//***************************************************************************** +// +// The GPIO port to check for a forced update. This will be one of the +// GPIO_PORTx_BASE values, where "x" is replaced with the port name (such as +// B). The value of "x" should match the value of "x" for +// FORCED_UPDATE_PERIPH. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_PORT GPIO_PORTB_BASE + +//***************************************************************************** +// +// The pin to check for a forced update. This is a value between 0 and 7. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_PIN 4 + +//***************************************************************************** +// +// The polarity of the GPIO pin that results in a forced update. This value +// should be 0 if the pin should be low and 1 if the pin should be high. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_POLARITY 0 + +//***************************************************************************** +// +// This enables a weak pull up for the GPIO pin used in a forced update. This +// value should be 0 if the pin should be have an internal weak pull down and +// 1 if the pin should have an interal weak pull up. +// Only FORCED_UPDATE_WPU or FORCED_UPDATE_WPD or neither should be defined. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_WPU +//#define FORCED_UPDATE_WPD + +//***************************************************************************** +// +// This enables the use of the GPIO_LOCK mechanism for configuration of +// protected GPIO pins (for example JTAG pins). If this value is not defined, +// the locking mechanism will not be used. The only legal values for this +// feature are GPIO_LOCK_KEY for Fury devices and GPIO_LOCK_KEY_DD for all +// other devices except Sandstorm devices, which do not support this feature. +// +// Depends on: ENABLE_UPDATE_CHECK +// Exclusive of: None +// Requries: None +// +//***************************************************************************** +//#define FORCED_UPDATE_KEY GPIO_LOCK_KEY +//#define FORCED_UPDATE_KEY GPIO_LOCK_KEY_DD + +//***************************************************************************** +// +// Selects the UART as the port for communicating with the boot loader. +// +// Depends on: None +// Exclusive of: CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE, +// SSI_ENABLE_UPDATE, USB_ENABLE_UPDATE +// Requires: UART_AUTOBAUD or UART_FIXED_BAUDRATE, UART_CLOCK_ENABLE, +// UARTx_BASE, UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE, +// UART_RXPIN_PCTL, UART_RXPIN_POS, UART_TXPIN_CLOCK_ENABLE, +// UART_TXPIN_BASE, UART_TXPIN_PCTL and UART_TXPIN_POS +// +//***************************************************************************** +//#define UART_ENABLE_UPDATE + +//***************************************************************************** +// +// Enables automatic baud rate detection. This can be used if the crystal +// frequency is unknown, or if operation at different baud rates is desired. +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: UART_FIXED_BAUDRATE +// Requires: None +// +//***************************************************************************** +//#define UART_AUTOBAUD + +//***************************************************************************** +// +// Selects the baud rate to be used for the UART. +// +// Depends on: UART_ENABLE_UPDATE, CRYSTAL_FREQ +// Exclusive of: UART_AUTOBAUD +// Requires: None +// +//***************************************************************************** +//#define UART_FIXED_BAUDRATE 115200 + +//***************************************************************************** +// +// Selects the clock enable for the UART peripheral module +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UARTx_BASE +// +//***************************************************************************** +//#define UART_CLOCK_ENABLE SYSCTL_RCGCUART_R0 + +//***************************************************************************** +// +// Selects the base address of the UART peripheral module +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_CLOCK_ENABLE +// +//***************************************************************************** +//#define UARTx_BASE UART0_BASE + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to UART RX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_RXPIN_BASE, UART_RXPIN_PCTL and UART_RXPIN_POS +// +//***************************************************************************** +//#define UART_RXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to UART RX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_PCTL and UART_RXPIN_POS +// +//***************************************************************************** +//#define UART_RXPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to UART RX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_POS +// +//***************************************************************************** +//#define UART_RXPIN_PCTL 0x1 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to UART RX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_PCTL +// +//***************************************************************************** +//#define UART_RXPIN_POS 0 + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to UART TX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_TXPIN_BASE, UART_TXPIN_PCTL and UART_TXPIN_POS +// +//***************************************************************************** +//#define UART_TXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to UART TX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_PCTL and UART_TXPIN_POS +// +//***************************************************************************** +//#define UART_TXPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to UART TX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_POS +// +//***************************************************************************** +//#define UART_TXPIN_PCTL 0x1 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to UART TX pin +// +// Depends on: UART_ENABLE_UPDATE +// Exclusive of: None +// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_PCTL +// +//***************************************************************************** +//#define UART_TXPIN_POS 1 + +//***************************************************************************** +// +// Selects the SSI port as the port for communicating with the boot loader. +// +// Depends on: None +// Exclusive of: CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE, +// UART_ENABLE_UPDATE, USB_ENABLE_UPDATE +// Requires: SSI_CLOCK_ENABLE, SSIx_BASE, SSI_CLKPIN_CLOCK_ENABLE, +// SSI_CLKPIN_BASE, SSI_CLKPIN_PCTL, SSI_CLKPIN_POS, +// SSI_FSSPIN_CLOCK_ENABLE, SSI_FSSPIN_BASE, SSI_FSSPIN_PCTL, +// SSI_FSSPIN_POS, SSI_MISOPIN_CLOCK_ENABLE, SSI_MISOPIN_BASE, +// SSI_MISOPIN_PCTL, SSI_MISOPIN_POS, SSI_MOSIPIN_CLOCK_ENABLE, +// SSI_MOSIPIN_BASE, SSI_MOSIPIN_PCTL and SSI_MOSIPIN_POS +// +//***************************************************************************** +//#define SSI_ENABLE_UPDATE + +//***************************************************************************** +// +// Selects the clock enable for the SSI peripheral module +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSIx_BASE +// +//***************************************************************************** +//#define SSI_CLOCK_ENABLE SYSCTL_RCGCSSI_R0 + +//***************************************************************************** +// +// Selects the base address of the SSI peripheral module +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_CLOCK_ENABLE +// +//***************************************************************************** +//#define SSIx_BASE SSI0_BASE + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to SSI CLK pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_CLKPIN_BASE, SSI_CLKPIN_PCTL and SSI_CLKPIN_POS +// +//***************************************************************************** +//#define SSI_CLKPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to SSI CLK pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_CLKPIN_CLOCK_ENABLE, SSI_CLKPIN_PCTL and SSI_CLKPIN_POS +// +//***************************************************************************** +//#define SSI_CLKPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to SSI CLK pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_CLKPIN_CLOCK_ENABLE, SSI_CLKPIN_BASE and SSI_CLKPIN_POS +// +//***************************************************************************** +//#define SSI_CLKPIN_PCTL 0x2 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to SSI CLK pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_CLKPIN_CLOCK_ENABLE, SSI_CLKPIN_BASE and SSI_CLKPIN_PCTL +// +//***************************************************************************** +//#define SSI_CLKPIN_POS 2 + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to SSI FSS pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_FSSPIN_BASE, SSI_FSSPIN_PCTL and SSI_FSSPIN_POS +// +//***************************************************************************** +//#define SSI_FSSPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to SSI FSS pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_FSSPIN_CLOCK_ENABLE, SSI_FSSPIN_PCTL and SSI_FSSPIN_POS +// +//***************************************************************************** +//#define SSI_FSSPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to SSI FSS pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_FSSPIN_CLOCK_ENABLE, SSI_FSSPIN_BASE and SSI_FSSPIN_POS +// +//***************************************************************************** +//#define SSI_FSSPIN_PCTL 0x2 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to SSI FSS pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_FSSPIN_CLOCK_ENABLE, SSI_FSSPIN_BASE and SSI_FSSPIN_PCTL +// +//***************************************************************************** +//#define SSI_FSSPIN_POS 3 + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to SSI MISO pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MISOPIN_BASE, SSI_MISOPIN_PCTL and SSI_MISOPIN_POS +// +//***************************************************************************** +//#define SSI_MISOPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to SSI MISO pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MISOPIN_CLOCK_ENABLE, SSI_MISOPIN_PCTL and SSI_MISOPIN_POS +// +//***************************************************************************** +//#define SSI_MISOPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to SSI MISO pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MISOPIN_CLOCK_ENABLE, SSI_MISOPIN_BASE and SSI_MISOPIN_POS +// +//***************************************************************************** +//#define SSI_MISOPIN_PCTL 0x2 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to SSI MISO pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MISOPIN_CLOCK_ENABLE, SSI_MISOPIN_BASE and SSI_MISOPIN_PCTL +// +//***************************************************************************** +//#define SSI_MISOPIN_POS 5 + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to SSI MOSI pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MOSIPIN_BASE, SSI_MOSIPIN_PCTL and SSI_MOSIPIN_POS +// +//***************************************************************************** +//#define SSI_MOSIPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to SSI MOSI pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MOSIPIN_CLOCK_ENABLE, SSI_MOSIPIN_PCTL and SSI_MOSIPIN_POS +// +//***************************************************************************** +//#define SSI_MOSIPIN_BASE GPIO_PORTA_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to SSI MOSI pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MOSIPIN_CLOCK_ENABLE, SSI_MOSIPIN_BASE and SSI_MOSIPIN_POS +// +//***************************************************************************** +//#define SSI_MOSIPIN_PCTL 0x2 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to SSI MOSI pin +// +// Depends on: SSI_ENABLE_UPDATE +// Exclusive of: None +// Requires: SSI_MOSIPIN_CLOCK_ENABLE, SSI_MOSIPIN_BASE and SSI_MOSIPIN_PCTL +// +//***************************************************************************** +//#define SSI_MOSIPIN_POS 4 + +//***************************************************************************** +// +// Selects the I2C port as the port for communicating with the boot loader. +// +// Depends on: None +// Exclusive of: CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, SSI_ENABLE_UPDATE, +// UART_ENABLE_UPDATE, USB_ENABLE_UPDATE +// Requires: I2C_SLAVE_ADDR, I2C_CLOCK_ENABLE, I2Cx_BASE, +// I2C_SCLPIN_CLOCK_ENABLE, I2C_SCLPIN_BASE, I2C_SCLPIN_PCTL, +// I2C_SCLPIN_POS, I2C_SDAPIN_CLOCK_ENABLE, I2C_SDAPIN_BASE, +// I2C_SDAPIN_PCTL and I2C_SDAPIN_POS +// +//***************************************************************************** +//#define I2C_ENABLE_UPDATE + +//***************************************************************************** +// +// Specifies the I2C address of the boot loader. +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define I2C_SLAVE_ADDR 0x42 + +//***************************************************************************** +// +// Selects the clock enable for the I2C peripheral module +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2Cx_BASE +// +//***************************************************************************** +//#define I2C_CLOCK_ENABLE SYSCTL_RCGCI2C_R0 + +//***************************************************************************** +// +// Selects the base address of the I2C peripheral module +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_CLOCK_ENABLE +// +//***************************************************************************** +//#define I2Cx_BASE I2C0_BASE + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to I2C SCL pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SCLPIN_BASE, I2C_SCLPIN_PCTL and I2C_SCLPIN_POS +// +//***************************************************************************** +//#define I2C_SCLPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R1 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to I2C SCL pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SCLPIN_CLOCK_ENABLE, I2C_SCLPIN_PCTL and I2C_SCLPIN_POS +// +//***************************************************************************** +//#define I2C_SCLPIN_BASE GPIO_PORTB_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to I2C SCL pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SCLPIN_CLOCK_ENABLE, I2C_SCLPIN_BASE and I2C_SCLPIN_POS +// +//***************************************************************************** +//#define I2C_SCLPIN_PCTL 0x3 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to I2C SCL pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SCLPIN_CLOCK_ENABLE, I2C_SCLPIN_BASE and I2C_SCLPIN_PCTL +// +//***************************************************************************** +//#define I2C_SCLPIN_POS 2 + +//***************************************************************************** +// +// Selects the clock enable for the GPIO corresponding to I2C SDA pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SDAPIN_BASE, I2C_SDAPIN_PCTL and I2C_SDAPIN_POS +// +//***************************************************************************** +//#define I2C_SDAPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R1 + +//***************************************************************************** +// +// Selects the base address for the GPIO corresponding to I2C SDA pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SDAPIN_CLOCK_ENABLE, I2C_SDAPIN_PCTL and I2C_SDAPIN_POS +// +//***************************************************************************** +//#define I2C_SDAPIN_BASE GPIO_PORTB_BASE + +//***************************************************************************** +// +// Selects the port control value for the GPIO corresponding to I2C SDA pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SDAPIN_CLOCK_ENABLE, I2C_SDAPIN_BASE and I2C_SDAPIN_POS +// +//***************************************************************************** +//#define I2C_SDAPIN_PCTL 0x3 + +//***************************************************************************** +// +// Selects the pin number for the GPIO corresponding to I2C SDA pin +// +// Depends on: I2C_ENABLE_UPDATE +// Exclusive of: None +// Requires: I2C_SDAPIN_CLOCK_ENABLE, I2C_SDAPIN_BASE and I2C_SDAPIN_PCTL +// +//***************************************************************************** +//#define I2C_SDAPIN_POS 3 + +//***************************************************************************** +// +// Selects Ethernet update via the BOOTP/TFTP protocol. +// +// Depends on: None +// Exclusive of: CAN_ENABLE_UPDATE, I2C_ENABLE_UPDATE, SSI_ENABLE_UPDATE, +// UART_ENABLE_UPDATE, USB_ENABLE_UPDATE +// Requires: CRYSTAL_FREQ +// +//***************************************************************************** +//#define ENET_ENABLE_UPDATE + +//***************************************************************************** +// +// Selects if the Ethernet LEDs should be enabled. +// +// Depends on: ENET_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENET_ENABLE_LEDS + +//***************************************************************************** +// +// Selects the Ethernet MAC address. If not specified, the MAC address is +// taken from the user registers. +// +// Depends on: ENET_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENET_MAC_ADDR0 0x00 +//#define ENET_MAC_ADDR1 0x00 +//#define ENET_MAC_ADDR2 0x00 +//#define ENET_MAC_ADDR3 0x00 +//#define ENET_MAC_ADDR4 0x00 +//#define ENET_MAC_ADDR5 0x00 + +//***************************************************************************** +// +// Sets the name of the BOOTP server to use. This can be used to request that +// a particular BOOTP server respond to our request; the value will be either +// the server's name, or a nickname used by that server. If not defined then +// any BOOTP server is allowed to respond. +// +// Depends on: ENET_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define ENET_BOOTP_SERVER "tiva" + +//***************************************************************************** +// +// Selects USB update via Device Firmware Update class. +// +// Depends on: None +// Exclusive of: CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE, +// SSI_ENABLE_UPDATE, UART_ENABLE_UPDATE, +// Requires: CRYSTAL_FREQ, USB_VENDOR_ID, USB_PRODUCT_ID +// +//***************************************************************************** +//#define USB_ENABLE_UPDATE + +//***************************************************************************** +// +// The USB vendor ID published by the DFU device. This value is the TI +// Tiva vendor ID. Change this to the vendor ID you have been assigned by +// USB-IF. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_VENDOR_ID 0x1cbe + +//***************************************************************************** +// +// The USB device ID published by the DFU device. If you are using your own +// vendor ID, chose a device ID that is different from the ID you use in +// non-update operation. If you have sublicensed TI's vendor ID, you must +// use an assigned product ID here. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_PRODUCT_ID 0x00ff + +//***************************************************************************** +// +// Selects the BCD USB device release number published in the device +// descriptor. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DEVICE_ID 0x0001 + +//***************************************************************************** +// +// Sets the maximum power consumption that the DFU device will report to the +// USB host in the configuration descriptor. Units are milliamps. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_MAX_POWER 150 + +//***************************************************************************** +// +// Determines whether the DFU device reports to the host that it is self +// powered (defined as 0) or bus powered (defined as 1). +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_BUS_POWERED 1 + +//***************************************************************************** +// +// Specifies the GPIO peripheral associated with the USB host/device mux. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: USB_MUX_PERIPH, USB_MUX_PORT, USB_MUX_PIN, USB_MUX_DEVICE +// +//***************************************************************************** +//#define USB_HAS_MUX + +//***************************************************************************** +// +// Specifies the GPIO peripheral associated with the USB host/device mux. +// +// Depends on: USB_ENABLE_UPDATE, USB_HAS_MUX +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_MUX_PERIPH SYSCTL_RCGC2_GPIOH + +//***************************************************************************** +// +// Specifies the GPIO port associated with the USB host/device mux. +// +// Depends on: USB_ENABLE_UPDATE, USB_HAS_MUX +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_MUX_PORT GPIO_PORTH_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number used to switch the USB host/device mux. Valid +// values are 0 through 7. +// +// Depends on: USB_ENABLE_UPDATE, USB_HAS_MUX +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_MUX_PIN 2 + +//***************************************************************************** +// +// Specifies the state to set the GPIO pin to to select USB device mode via +// the USB host/device mux. Valid values are 1 (high) or 0 (low). +// +// Depends on: USB_ENABLE_UPDATE, USB_HAS_MUX +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_MUX_DEVICE 1 + +//***************************************************************************** +// +// Specifies whether the target board requires configuration of the pin used +// for VBUS. This applies to Blizzard class and later devices. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: USB_VBUS_PERIPH, USB_VBUS_PORT, USB_VBUS_PIN +// +//***************************************************************************** +//#define USB_VBUS_CONFIG + +//***************************************************************************** +// +// Specifies the GPIO peripheral containing the pin which is used for VBUS. +// The value is of the form SYSCTL_RCGCGPIO_Rx, where the Rx represents +// the required GPIO port. This applies to Blizzard class and later +// devices. +// +// Depends on: USB_ENABLE_UPDATE, USB_VBUS_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_VBUS_PERIPH SYSCTL_RCGCGPIO_R1 + +//***************************************************************************** +// +// Specifies the GPIO port containing the pin which is used for VBUS. The value +// is of the form GPIO_PORTx_BASE, where PORTx represents the required GPIO +// port. +// +// Depends on: USB_ENABLE_UPDATE, USB_VBUS_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_VBUS_PORT GPIO_PORTB_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number used for VBUS. Valid values are 0 through 7. +// +// Depends on: USB_ENABLE_UPDATE, USB_VBUS_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_VBUS_PIN 1 + +//***************************************************************************** +// +// Specifies whether the target board requires configuration of the pin used +// for ID. This applies to Blizzard class and later devices. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: USB_ID_PERIPH, USB_ID_PORT, USB_ID_PIN +// +//***************************************************************************** +//#define USB_ID_CONFIG + +//***************************************************************************** +// +// Specifies the GPIO peripheral containing the pin which is used for ID. +// The value is of the form SYSCTL_RCGCGPIO_Rx, where the Rx represents +// the required GPIO port. This applies to Blizzard class and later +// devices. +// +// Depends on: USB_ENABLE_UPDATE, USB_ID_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_ID_PERIPH SYSCTL_RCGCGPIO_R1 + +//***************************************************************************** +// +// Specifies the GPIO port containing the pin which is used for ID. The value +// is of the form GPIO_PORTx_BASE, where PORTx represents the required GPIO +// port. +// +// Depends on: USB_ENABLE_UPDATE, USB_ID_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_ID_PORT GPIO_PORTB_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number used for ID. Valid values are 0 through 7. +// +// Depends on: USB_ENABLE_UPDATE, USB_ID_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_ID_PIN 0 + +//***************************************************************************** +// +// Specifies whether the target board requires configuration of the pin used +// for DP. This applies to Blizzard class and later devices. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: USB_DP_PERIPH, USB_DP_PORT, USB_DP_PIN +// +//***************************************************************************** +//#define USB_DP_CONFIG + +//***************************************************************************** +// +// Specifies the GPIO peripheral containing the pin which is used for DP. +// The value is of the form SYSCTL_RCGCGPIO_Rx, where the Rx represents +// the required GPIO port. This applies to Blizzard class and later +// devices. +// +// Depends on: USB_ENABLE_UPDATE, USB_DP_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DP_PERIPH SYSCTL_RCGCGPIO_R10 + +//***************************************************************************** +// +// Specifies the GPIO port containing the pin which is used for DP. The value +// is of the form GPIO_PORTx_BASE, where PORTx represents the required GPIO +// port. +// +// Depends on: USB_ENABLE_UPDATE, USB_DP_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DP_PORT GPIO_PORTL_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number used for DP. Valid values are 0 through 7. +// +// Depends on: USB_ENABLE_UPDATE, USB_DP_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DP_PIN 6 + +//***************************************************************************** +// +// Specifies whether the target board requires configuration of the pin used +// for DM. This applies to Blizzard class and later devices. +// +// Depends on: USB_ENABLE_UPDATE +// Exclusive of: None +// Requires: USB_DM_PERIPH, USB_DM_PORT, USB_DM_PIN +// +//***************************************************************************** +//#define USB_DM_CONFIG + +//***************************************************************************** +// +// Specifies the GPIO peripheral containing the pin which is used for DM. +// The value is of the form SYSCTL_RCGCGPIO_Rx, where the Rx represents +// the required GPIO port. This applies to Blizzard class and later +// devices. +// +// Depends on: USB_ENABLE_UPDATE, USB_DM_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DM_PERIPH SYSCTL_RCGCGPIO_R10 + +//***************************************************************************** +// +// Specifies the GPIO port containing the pin which is used for DM. The value +// is of the form GPIO_PORTx_BASE, where PORTx represents the required GPIO +// port. +// +// Depends on: USB_ENABLE_UPDATE, USB_DM_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DM_PORT GPIO_PORTL_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number used for DM. Valid values are 0 through 7. +// +// Depends on: USB_ENABLE_UPDATE, USB_DM_CONFIG +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define USB_DM_PIN 7 + +//***************************************************************************** +// +// Selects the CAN port as the port for communicating with the boot loader. +// +// Depends on: None +// Exclusive of: ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE, SSI_ENABLE_UPDATE, +// UART_ENABLE_UPDATE, USB_ENABLE_UPDATE +// Requires: CAN_RX_PERIPH, CAN_RX_PORT, CAN_RX_PIN, CAN_TX_PERIPH, +// CAN_TX_PORT, CAN_TX_PIN, CAN_BIT_RATE, CRYSTAL_FREQ. +// +//***************************************************************************** +//#define CAN_ENABLE_UPDATE + +//***************************************************************************** +// +// Enables the UART to CAN bridging for use when the CAN port is selected for +// communicating with the boot loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_UART_BRIDGE + +//***************************************************************************** +// +// Specifies the GPIO peripheral associated with CAN0 RX pin used by the boot +// loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_RX_PERIPH SYSCTL_RCGC2_GPIOA + +//***************************************************************************** +// +// Specifies the GPIO port associated with CAN0 RX pin used by the boot loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_RX_PORT GPIO_PORTA_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number associated with CAN0 RX pin used by the boot +// loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_RX_PIN 4 + +//***************************************************************************** +// +// Specifies the GPIO peripheral associated with CAN0 TX pin used by the boot +// loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_TX_PERIPH SYSCTL_RCGC2_GPIOA + +//***************************************************************************** +// +// Specifies the GPIO port associated with CAN0 TX pin used by the boot loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_TX_PORT GPIO_PORTA_BASE + +//***************************************************************************** +// +// Specifies the GPIO pin number associated with CAN0 TX pin used by the boot +// loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_TX_PIN 5 + +//***************************************************************************** +// +// Specifies the bit rate for CAN0 used by the boot loader. +// +// Depends on: CAN_ENABLE_UPDATE +// Exclusive of: None +// Requires: None +// +//***************************************************************************** +//#define CAN_BIT_RATE 1000000 + +//***************************************************************************** +// +// Boot loader hook functions. +// +// The following defines allow you to add application-specific function which +// are called at various points during boot loader execution. +// +//***************************************************************************** + +//***************************************************************************** +// +// Performs application-specific low level hardware initialization on system +// reset. +// +// If hooked, this function will be called immediately after the boot loader +// code relocation completes. An application may perform any required low +// hardware initialization during this function. Note that the system clock +// has not been set when this function is called. Initialization that assumes +// the system clock is set may be performed in the BL_INIT_FN_HOOK function +// instead. +// +// void MyHwInitFunc(void); +// +//***************************************************************************** +//#define BL_HW_INIT_FN_HOOK MyHwInitFunc + +//***************************************************************************** +// +// Performs application-specific initialization on system reset. +// +// If hooked, this function will be called immediately after the boot loader +// sets the system clock. An application may perform any additional +// initialization during this function. +// +// void MyInitFunc(void); +// +//***************************************************************************** +//#define BL_INIT_FN_HOOK MyInitFunc + +//***************************************************************************** +// +// Performs application-specific reinitialization on boot loader entry via SVC. +// +// If hooked, this function will be called immediately after the boot loader +// reinitializes the system clock when it is entered from an application +// via the SVC mechanism rather than as a result of a system reset. An +// application may perform any additional reinitialization in this function. +// +// void MyReinitFunc(void); +// +//***************************************************************************** +//#define BL_REINIT_FN_HOOK MyReinitFunc + +//***************************************************************************** +// +// Informs an application that a download is starting. +// +// If hooked, this function will be called when a new firmware download is +// about to start. The application may use this signal to initialize any +// progress display. +// +// void MyStartFunc(void); +// +//***************************************************************************** +//#define BL_START_FN_HOOK MyStartFunc + +//***************************************************************************** +// +// Informs an application of download progress. +// +// If hooked, this function will be called periodically during firmware +// download. The application may use this to update its user interface. +// When using a protocol which does not inform the client of the final size of +// the download in advance (e.g. TFTP), the ulTotal parameter will be 0, +// otherwise it indicates the expected size of the complete download. +// +// void MyProgressFunc(unsigned long ulCompleted, unsigned long ulTotal); +// +// where: +// +// - ulCompleted indicates the number of bytes already downloaded. +// - ulTotal indicates the number of bytes expected or 0 if this is not known. +// +//***************************************************************************** +//#define BL_PROGRESS_FN_HOOK MyProgressFunc + +//***************************************************************************** +// +// Informs an application that a download has completed. +// +// If hooked, this function will be called when a firmware download ends. +// The application may use this signal to update its user interface. Typically +// a system reset will occur shortly after this function returns as the boot +// loader attempts to boot the new image. +// +// void MyEndFunc(void); +// +//***************************************************************************** +//#define BL_END_FN_HOOK MyEndFunc + +//***************************************************************************** +// +// Allows an application to perform in-place data decryption during download. +// +// If hooked, this function will be called on receipt of any new block of +// downloaded firmware image data. The application must decrypt this data +// in place then return at which point the boot loader will write the data to +// flash. +// +// void MyDecryptionFunc(unsigned char *pucBuffer, unsigned long ulSize); +// +// where: +// +// - pucBuffer points to the first byte of data to be decrypted. +// - ulSize indicates the number of bytes of data at pucBuffer. +// +//***************************************************************************** +//#define BL_DECRYPT_FN_HOOK MyDecryptionFunc + +//***************************************************************************** +// +// Allows an application to force a new firmware download. +// +// If hooked, this function will be called after a system reset (following +// basic initialization and the initialization hook function) to give the +// application an opportunity to force a new firmware download. Depending upon +// the return code, the boot loader will either boot the existing firmware +// image or wait for a new download to be started. +// +// Note that this hook takes precedence over ENABLE_UPDATE_CHECK settings. If +// the hook function is defined, the basic GPIO check offered by +// ENABLE_UPDATE_CHECK does not take place. +// +// unsigned long MyCheckUpdateFunc(void); +// +// where the return code is 0 if the boot loader should boot the existing +// image (if found) or non-zero to indicate that the boot loader should retain +// control and wait for a new firmware image to be downloaded. +// +//***************************************************************************** +//#define BL_CHECK_UPDATE_FN_HOOK MyCheckUpdateFunc + +//***************************************************************************** +// +// Allows an application to replace the flash block erase function. +// +// If hooked, this function will be called whenever a block of flash is to +// be erased. The function must erase the block and block until the operation +// has completed. The size of the block which will be erased is defined by +// FLASH_BLOCK_SIZE. +// +// void MyFlashEraseFunc(unsigned long ulBlockAddr); +// +// where: +// +// - ulBlockAddr is the address of the flash block to be erased. +// +//***************************************************************************** +//#define BL_FLASH_ERASE_FN_HOOK MyFlashEraseFunc + +//***************************************************************************** +// +// Allows an application to replace the flash programming function. +// +// If hooked, this function will be called whenever a block of data is to be +// be written to flash. The function must program the supplied data and block +// until the operation has has completed. +// +// void MyFlashProgramFunc(unsigned long ulDstAddr, +// unsigned char *pucSrcData, +// unsigned long ulLength); +// +// where: +// +// - ulDstAddr is the address in flash at which the data is to be programmed. +// This must be a multiple of 4. +// - pucSrcData points to the first byte of the data to program. +// - ulLength is the number of bytes of data to program. This must be a +// multiple of 4. +// +//***************************************************************************** +//#define BL_FLASH_PROGRAM_FN_HOOK MyFlashProgramFunc + +//***************************************************************************** +// +// Allows an application to replace the flash error clear function. +// +// If hooked, this function will be called before each flash erase or program +// operation. The function must clear any flash error indicators and prepare +// to detect access violations that may occur in a future erase or program +// operation. +// +// void MyFlashClearErrorFunc(void); +// +//***************************************************************************** +//#define BL_FLASH_CL_ERR_FN_HOOK MyFlashClearErrorFunc + +//***************************************************************************** +// +// Reports whether or not a flash access violation error has occurred. +// +// If hooked, this function will be called after flash erase or program +// operations. The return code indicates to the caller whether or not +// an access violation error has occurred since the last call to the function +// defined by BL_FLASH_CL_ERR_FN_HOOK. +// +// unsigned long MyFlashErrorFunc(void); +// +// where the return code is 0 if no error has occurred or non-zero if an +// error was detected. +// +//***************************************************************************** +//#define BL_FLASH_ERROR_FN_HOOK MyFlashErrorFunc + +//***************************************************************************** +// +// Reports the total size of the device flash. +// +// If hooked, this function will be called to determine the size of the flash +// device. +// +// unsigned long MyFlashSizeFunc(void); +// +// where the return code is the total number of bytes of flash supported by the +// device. Note that this does not take into account any reserved space +// defined via the FLASH_RSVD_SPACE value in this header file. +// +//***************************************************************************** +//#define BL_FLASH_SIZE_FN_HOOK MyFlashSizeFunc + +//***************************************************************************** +// +// Reports the address of the first byte after the end of the device flash. +// +// If hooked, this function will be called to determine the address of the end +// of valid flash. +// +// unsigned long MyFlashEndFunc(void); +// +// where the return code is the address of the first byte after the end of flash. +// Note that this does not take into account any reserved space defined via +// the FLASH_RSVD_SPACE value in this header file. +// +//***************************************************************************** +//#define BL_FLASH_END_FN_HOOK MyFlashEndFunc + +//***************************************************************************** +// +// Checks whether the start address and size of an image are valid. +// +// If hooked, this function will be called whenever a new download is to be +// started. It determines whether or not an image of a particular size may be +// flashed at a given address. Valid addresses are: +// +// 1. APP_START_ADDRESS in all cases. +// 2. 0x00000000 if ENABLE_BL_UPDATE is defined. +// 3. The start of the reserved space if FLASH_RSVD_SPACE is defined. +// +// unsigned long MyFlashAddrCheckFunc(unsigned long ulAddr, +// unsigned long ulSize); +// +// where: +// +// - ulAddr is the address in flash at which the image is to be programmed. +// - ulSize is the total size of the image if known or 0 otherwise. +// +// The return code will be 0 if the address or size is invalid or a non-zero +// value if valid. +// +//***************************************************************************** +//#define BL_FLASH_AD_CHECK_FN_HOOK MyFlashAddrCheckFunc + +#endif // __BL_CONFIG_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.c new file mode 100644 index 0000000000000000000000000000000000000000..dff70140beeff6a254df2d44b219498c7ab5b5d1 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.c @@ -0,0 +1,267 @@ +//***************************************************************************** +// +// bl_crc32.c - CRC32 calculation functions used in the boot loader. +// +// Copyright (c) 2013-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** +#include +#include +#include "inc/hw_types.h" +#include "inc/hw_flash.h" +#include "inc/hw_sysctl.h" +#include "bl_config.h" +#include "boot_loader/bl_crc32.h" + +//***************************************************************************** +// +// Storage for the CRC32 calculation lookup table. +// +//***************************************************************************** +static uint32_t g_pui32CRC32Table[256]; + +//***************************************************************************** +// +// Initialize the CRC32 calculation table for the polynomial used. We pick +// the commonly used ANSI X 3.66 polymonial. This code was informed by an +// example found at http://www.createwindow.com/programming/crc32/index.htm. +// +//***************************************************************************** +static uint32_t +Reflect(uint32_t ui32Ref, uint8_t ui8Ch) +{ + uint_fast32_t ui32Value; + int_fast16_t i16Loop; + + // + // Clear our accumulator variable. + // + ui32Value = 0; + + // + // Swap bit 0 for bit 7, bit 1 for bit 6, etc. + // + for(i16Loop = 1; i16Loop < (ui8Ch + 1); i16Loop++) + { + if(ui32Ref & 1) + { + ui32Value |= 1 << (ui8Ch - i16Loop); + } + ui32Ref >>= 1; + } + + // + // Return the reflected value. + // + return(ui32Value); +} + +//***************************************************************************** +// +// Initialize the lookup table used in calculating the CRC32 value. +// +//***************************************************************************** +void +InitCRC32Table(void) +{ + uint_fast32_t ui32Polynomial; + int_fast16_t i16Loop, i16Bit; + + // + // This is the ANSI X 3.66 polynomial as required by the DFU + // specification. + // + ui32Polynomial = 0x04c11db7; + + for(i16Loop = 0; i16Loop <= 0xFF; i16Loop++) + { + g_pui32CRC32Table[i16Loop]=Reflect(i16Loop, 8) << 24; + for (i16Bit = 0; i16Bit < 8; i16Bit++) + { + g_pui32CRC32Table[i16Loop] = ((g_pui32CRC32Table[i16Loop] << 1) ^ + (g_pui32CRC32Table[i16Loop] & + ((uint32_t)1 << 31) ? + ui32Polynomial : 0)); + } + g_pui32CRC32Table[i16Loop] = Reflect(g_pui32CRC32Table[i16Loop], 32); + } +} + +//***************************************************************************** +// +// Calculate the CRC for the supplied block of data. +// +//***************************************************************************** +uint32_t +CalculateCRC32(uint8_t *pui8Data, uint32_t ui32Length, uint32_t ui32CRC) +{ + uint32_t ui32Count; + uint8_t *pui8Buffer; + uint8_t ui8Char; + + // + // Get a pointer to the start of the data and the number of bytes to + // process. + // + pui8Buffer = pui8Data; + ui32Count = ui32Length; + + // + // Perform the algorithm on each byte in the supplied buffer using the + // lookup table values calculated in InitCRC32Table(). + // + while(ui32Count--) + { + ui8Char = *pui8Buffer++; + ui32CRC = (ui32CRC >> 8) ^ g_pui32CRC32Table[(ui32CRC & 0xFF) ^ + ui8Char]; + } + + // + // Return the result. + // + return(ui32CRC); +} + +//***************************************************************************** +// +//! Checks that the embedded CRC in the image matches the expected value. +//! +//! \param pui32Image points to the start of the firmware image in memory. +//! +//! This function finds the firmware image information header and verifies that +//! the embedded CRC32 matches one calculated over the image. +//! +//! \return Returns \b CHECK_CRC_OK if the CRC calculated matches the value +//! embedded in the image, \b CHECK_CRC_NO_HEADER if no image information +//! header was found at the top of the vector table, \b CHECK_CRC_BAD_CRC if +//! an embedded CRC was found but did not match the calculated value or \b +//! CHECK_CRC_ZERO_LENGTH if the length field of the image information header +//! contains 0 (likely indicating that the image had not been run through the +//! binpack tool which inserts the length and CRC values into the header). +// +//***************************************************************************** +uint32_t +CheckImageCRC32(uint32_t *pui32Image) +{ + uint32_t ui32Loop, ui32FlashSize, ui32CRC; + + // + // Determine the size of flash (giving an upper bound for the image + // size). + // + if(CLASS_IS_TM4C129) + { + // + // Get the flash size from the FLASH_PP register. + // + ui32FlashSize = ((2048 * ((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1)) - + APP_START_ADDRESS); + } + else + { + // + // Compute the size of the flash. + // + ui32FlashSize = (((HWREG(FLASH_FSIZE) & FLASH_FSIZE_SIZE_M) << 11) + + 0x800 - APP_START_ADDRESS); + } + + // + // Scan for the image information header marker bytes. Given that the + // largest possible vector table includes 16 system exceptions and 240 + // IC-specific vectors, we only need to search 257 words into memory before + // giving up. + // + for(ui32Loop = 0; ui32Loop < 257; ui32Loop++) + { + // + // Have we found the header marker words? + // + if((pui32Image[ui32Loop] == 0xFF01FF02) && + (pui32Image[ui32Loop + 1] == 0xFF03FF04)) + { + // + // Yes. Check to see if the length field is 0xFFFFFFFF. This + // likely indicates that the image has not been processed by the + // binpack tool which adds the length and CRC information to the + // image header. + // + if(pui32Image[ui32Loop + 2] == 0xFFFFFFFF) + { + // + // The header reports an image size of 0 so we can't go on and + // check the CRC. + // + return(CHECK_CRC_NO_LENGTH); + } + + // + // Extract the image length and ensure that it is sensible + // given the flash size. We assume the length is invalid if it + // is larger than the available flash size or smaller than the + // space taken up by the vector table and header we've already + // scanned through. + // + if((pui32Image[ui32Loop + 2] > ui32FlashSize) || + (pui32Image[ui32Loop + 2] < + ((ui32Loop + 4) * sizeof(uint32_t)))) + { + // + // The header reports an image size that is larger than the + // available flash so this is obviously incorrect. Fail the + // check. + // + return(CHECK_CRC_BAD_LENGTH); + } + + // + // Calculate the CRC32 value for the image. Note that we skip the + // 4 bytes that hold the check CRC. + // + ui32CRC = CalculateCRC32((uint8_t *)pui32Image, + (ui32Loop + 3) * sizeof(uint32_t), + 0xffffffff); + ui32CRC = CalculateCRC32((uint8_t *)&pui32Image[ui32Loop + 4], + (pui32Image[ui32Loop + 2] - + ((ui32Loop + 4) * sizeof(uint32_t))), + ui32CRC); + ui32CRC ^= 0xffffffff; + + // + // Determine whether the calculated CRC matches the value stored + // in the image information header. + // + if(ui32CRC == pui32Image[ui32Loop + 3]) + { + return(CHECK_CRC_OK); + } + else + { + return(CHECK_CRC_BAD_CRC); + } + } + } + + // + // If we drop out the loop, there was no image information header so + // fail the call. + // + return(CHECK_CRC_NO_HEADER); +} diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.h new file mode 100644 index 0000000000000000000000000000000000000000..4c1b7ac0ef6f49511cd0fc333a7071f4480ffccb --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crc32.h @@ -0,0 +1,49 @@ +//***************************************************************************** +// +// bl_crc32.h - Public header for the boot loader CRC32 functions. +// +// Copyright (c) 2013-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CRC32_H__ +#define __BL_CRC32_H__ + +//***************************************************************************** +// +// Return codes generated by CheckImageCRC32(). +// +//***************************************************************************** +#define CHECK_CRC_OK 0 +#define CHECK_CRC_NO_HEADER 1 +#define CHECK_CRC_NO_LENGTH 2 +#define CHECK_CRC_BAD_LENGTH 3 +#define CHECK_CRC_BAD_CRC 4 + +//***************************************************************************** +// +// Exported function prototypes. +// +//***************************************************************************** +extern void InitCRC32Table(void); +extern uint32_t CheckImageCRC32(uint32_t *pui32Image); +extern uint32_t CalculateCRC32(uint8_t *pui8Data, uint32_t ui32Length, + uint32_t ui32CRC); + +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crystal.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crystal.h new file mode 100644 index 0000000000000000000000000000000000000000..66419e68ea7d6f03152a6e855058319390ecfc05 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_crystal.h @@ -0,0 +1,94 @@ +//***************************************************************************** +// +// bl_crystal.h - Macros to convert a CRYSTAL_FREQ value into the appropriate +// RCC XTAL field define. +// +// Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_CRYSTAL_H__ +#define __BL_CRYSTAL_H__ + +//***************************************************************************** +// +// Convert the CRYSTAL_FREQ value into the corresponding SYSCTL_RCC_XTAL_??? +// value for TM4C123 device. For TM4C129 device the CRYSTAL_FREQ is converted to +// M and N values for the PLL. +// +//***************************************************************************** +#if CRYSTAL_FREQ == 3579545 +#define XTAL_VALUE SYSCTL_RCC_XTAL_3_57MHZ +#elif CRYSTAL_FREQ == 3686400 +#define XTAL_VALUE SYSCTL_RCC_XTAL_3_68MHZ +#elif CRYSTAL_FREQ == 4000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_4MHZ +#elif CRYSTAL_FREQ == 4096000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_4_09MHZ +#elif CRYSTAL_FREQ == 4915200 +#define XTAL_VALUE SYSCTL_RCC_XTAL_4_91MHZ +#elif CRYSTAL_FREQ == 5000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_5MHZ +#define PLL_M_TO_REG 96 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 5120000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_5_12MHZ +#elif CRYSTAL_FREQ == 6000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_6MHZ +#define PLL_M_TO_REG 80 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 6144000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_6_14MHZ +#elif CRYSTAL_FREQ == 7372800 +#define XTAL_VALUE SYSCTL_RCC_XTAL_7_37MHZ +#elif CRYSTAL_FREQ == 8000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_8MHZ +#define PLL_M_TO_REG 60 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 8192000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_8_19MHZ +#elif CRYSTAL_FREQ == 10000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_10MHZ +#define PLL_M_TO_REG 48 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 12000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_12MHZ +#define PLL_M_TO_REG 40 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 12288000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_12_2MHZ +#elif CRYSTAL_FREQ == 13560000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_13_5MHZ +#elif CRYSTAL_FREQ == 14318180 +#define XTAL_VALUE SYSCTL_RCC_XTAL_14_3MHZ +#elif CRYSTAL_FREQ == 16000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_16MHZ +#define PLL_M_TO_REG 30 +#define PLL_N_TO_REG 0 +#elif CRYSTAL_FREQ == 16384000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_16_3MHZ +#elif CRYSTAL_FREQ == 25000000 +#define XTAL_VALUE SYSCTL_RCC_XTAL_25MHZ +#define PLL_M_TO_REG 96 +#define PLL_N_TO_REG 4 +#else +#error ERROR: Unknown CRYSTAL_FREQ value specified! +#endif + +#endif // __BL_CRYSTAL_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..4ecd346041c60200aae955e8907ebea3a68b2953 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.c @@ -0,0 +1,64 @@ +//***************************************************************************** +// +// bl_decrypt.c - Code for performing an in-place decryption of the firmware +// image as it is downloaded. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "bl_config.h" +#include "boot_loader/bl_decrypt.h" + +//***************************************************************************** +// +//! \addtogroup bl_decrypt_api +//! @{ +// +//***************************************************************************** +#if defined(ENABLE_DECRYPTION) || defined(DOXYGEN) + +//***************************************************************************** +// +//! Performs an in-place decryption of downloaded data. +//! +//! \param pui8Buffer is the buffer that holds the data to decrypt. +//! \param ui32Size is the size, in bytes, of the buffer that was passed in via +//! the \e pui8Buffer parameter. +//! +//! This function is a stub that could provide in-place decryption of the data +//! that is being downloaded to the device. +//! +//! \return None. +// +//***************************************************************************** +void +DecryptData(uint8_t *pui8Buffer, uint32_t ui32Size) +{ +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif + diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.h new file mode 100644 index 0000000000000000000000000000000000000000..033080f656a08359231088e599c5a18a16dfdfeb --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_decrypt.h @@ -0,0 +1,35 @@ +//***************************************************************************** +// +// bl_decrypt.h - Definitions for the decryption function. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_DECRYPT_H__ +#define __BL_DECRYPT_H__ + +//***************************************************************************** +// +// Prototype for the decryption function. +// +//***************************************************************************** +extern void DecryptData(uint8_t *pui8Buffer, uint32_t ui32Size); + +#endif // __BL_DECRYPT_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_emac.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_emac.c new file mode 100644 index 0000000000000000000000000000000000000000..b91d5d6b3ad64079b930323d6a494c6395a39b7c --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_emac.c @@ -0,0 +1,1930 @@ +//***************************************************************************** +// +// bl_emac.c - Functions to update via Ethernet. +// +// Copyright (c) 2013-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include +#include +#include "bl_config.h" +#include "inc/hw_emac.h" +#include "inc/hw_flash.h" +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "driverlib/gpio.h" +#include "driverlib/pin_map.h" +#include "driverlib/emac.h" +#include "driverlib/sysctl.h" +#include "boot_loader/bl_decrypt.h" +#include "boot_loader/bl_flash.h" +#include "boot_loader/bl_hooks.h" +#include "driverlib/rom.h" +// +// Define ROM_SysCtlClockFreqSet() for snowflake RA0. Even though this function +// is deprecated in RA0 ROM, the function operates correctly when +// SYSCTL_MOSCCTL register is configured correctly prior to calling this +// function. +// +#if defined(TARGET_IS_TM4C129_RA0) +#define ROM_SysCtlClockFreqSet \ + ((uint32_t (*)(uint32_t ui32Config, \ + uint32_t ui32SysClock))ROM_SYSCTLTABLE[48]) +#endif + +// +// Define MAP_GPIOPadConfigSet() for the Boot Loader for Snowflake. +// This function fails in Snowflake for higher drive strengths, it will work +// properly for the instances where it is used here in the boot loader. +// +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) +#define ROM_GPIOPadConfigSet \ + ((void (*)(uint32_t ui32Port, \ + uint8_t ui8Pins, \ + uint32_t ui32Strength, \ + uint32_t ui32PadType))ROM_GPIOTABLE[5]) +#endif + +// +// Define ROM_EMACInit for the bootloader of Snowflake RA0. This function is +// deprecated in RA0 ROM, as it does not disable some interrupts that are not +// cleared by ***_EMACIntClear(). But that is not a problem for the bootloader +// as we are not enabling any interrupts. +// +#if defined(TARGET_IS_TM4C129_RA0) +#define ROM_EMACInit \ + ((void (*)(uint32_t ui32Base, \ + uint32_t ui32SysClk, \ + uint32_t ui32BusConfig, \ + uint32_t ui32RxBurst, \ + uint32_t ui32TxBurst, \ + uint32_t ui32DescSkipSize))ROM_EMACTABLE[8]) +#endif + +#include "driverlib/rom_map.h" + +//***************************************************************************** +// +//! \addtogroup bl_emac_api +//! @{ +// +//***************************************************************************** + +#if defined(ENET_ENABLE_UPDATE) || defined(DOXYGEN) +//***************************************************************************** +// +// Make sure that the crystal frequency is defined. +// +//***************************************************************************** +#if !defined(CRYSTAL_FREQ) +#error ERROR: CRYSTAL_FREQ must be defined for Ethernet update! +#endif + +//***************************************************************************** +// +// Make sure that boot loader update is not enabled (it is not supported via +// BOOTP given that there is no way to distinguish between a normal firmware +// image and a boot loader update image). +// +//***************************************************************************** +#if defined(ENABLE_BL_UPDATE) +#error ERROR: Updating the boot loader is not supported over Ethernet! +#endif + +//***************************************************************************** +// +// TFTP packets contain 512 bytes of data and a packet shorter than this +// indicates the end of the transfer. +// +//***************************************************************************** +#define TFTP_BLOCK_SIZE 512 + +//***************************************************************************** +// +// uIP uses memset, so a simple one is provided here. This is not as efficient +// as the one in the C library (from an execution time perspective), but it is +// much smaller. +// +//***************************************************************************** +void * +my_memset(void *pvDest, int iChar, size_t i32Length) +{ + int8_t *pi8Buf = (int8_t *)pvDest; + + // + // Fill the buffer with the given character. + // + while(i32Length--) + { + *pi8Buf++ = iChar; + } + + // + // Return a pointer to the beginning of the buffer. + // + return(pvDest); +} + +//***************************************************************************** +// +// uIP uses memcpy, so a simple one is provided here. This is not as efficient +// as the one in the C library (from an execution time perspective), but it is +// much smaller. +// +//***************************************************************************** +void * +my_memcpy(void *pvDest, const void *pvSrc, size_t i32Length) +{ + const int8_t *pi8Src = (const int8_t *)pvSrc; + int8_t *pi8Dest = (int8_t *)pvDest; + + // + // Copy bytes from the source buffer to the destination buffer. + // + while(i32Length--) + { + *pi8Dest++ = *pi8Src++; + } + + // + // Return a pointer to the beginning of the destination buffer. + // + return(pvDest); +} + +//***************************************************************************** +// +// Directly include the uIP code if using Ethernet for the update. This allows +// non-Ethernet boot loader builds to not have to supply the uip-conf.h file +// that would otherwise be required. +// +//***************************************************************************** +#define memcpy my_memcpy +#define memset my_memset +#undef htonl +#undef ntohl +#undef htons +#undef ntohs +#include "third_party/uip-1.0/uip/pt.h" +#include "third_party/uip-1.0/uip/uip_arp.c" +#undef BUF +#include "third_party/uip-1.0/uip/uip.c" + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for a predictable length +// delay. +// +//***************************************************************************** +extern void Delay(uint32_t ui32Count); + +//***************************************************************************** +// +// Defines for setting up the system clock. +// +//***************************************************************************** +#define SYSTICKHZ 100 +#define SYSTICKMS (1000 / SYSTICKHZ) + +//***************************************************************************** +// +// UIP Timers (in ms) +// +//***************************************************************************** +#define UIP_PERIODIC_TIMER_MS 50 +#define UIP_ARP_TIMER_MS 10000 + +//***************************************************************************** +// +// This structure defines the fields in a BOOTP request/reply packet. +// +//***************************************************************************** +typedef struct +{ + // + // The operation; 1 is a request, 2 is a reply. + // + uint8_t ui8Op; + + // + // The hardware type; 1 is Ethernet. + // + uint8_t ui8HType; + + // + // The hardware address length; for Ethernet this will be 6, the length of + // the MAC address. + // + uint8_t ui8HLen; + + // + // Hop count, used by gateways for cross-gateway booting. + // + uint8_t ui8Hops; + + // + // The transaction ID. + // + uint32_t ui32XID; + + // + // The number of seconds elapsed since the client started trying to boot. + // + uint16_t ui16Secs; + + // + // The BOOTP flags. + // + uint16_t ui16Flags; + + // + // The client's IP address, if it knows it. + // + uint32_t ui32CIAddr; + + // + // The client's IP address, as assigned by the BOOTP server. + // + uint32_t ui32YIAddr; + + // + // The TFTP server's IP address. + // + uint32_t ui32SIAddr; + + // + // The gateway IP address, if booting cross-gateway. + // + uint32_t ui32GIAddr; + + // + // The hardware address; for Ethernet this is the MAC address. + // + uint8_t pui8CHAddr[16]; + + // + // The name, or nickname, of the server that should handle this BOOTP + // request. + // + char pcSName[64]; + + // + // The name of the boot file to be loaded via TFTP. + // + char pcFile[128]; + + // + // Optional vendor-specific area; not used for BOOTP. + // + uint8_t pui8Vend[64]; +} +tBOOTPPacket; + +//***************************************************************************** +// +// The BOOTP commands. +// +//***************************************************************************** +#define BOOTP_REQUEST 1 +#define BOOTP_REPLY 2 + +//***************************************************************************** +// +// The TFTP commands. +// +//***************************************************************************** +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 + +//***************************************************************************** +// +// The UDP ports used by the BOOTP protocol. +// +//***************************************************************************** +#define BOOTP_SERVER_PORT 67 +#define BOOTP_CLIENT_PORT 68 + +//***************************************************************************** +// +// The UDP port for the TFTP server. +// +//***************************************************************************** +#define TFTP_PORT 69 + +//***************************************************************************** +// +// The MAC address of the Ethernet interface. +// +//***************************************************************************** +#ifdef ENET_MAC_ADDR0 +static struct uip_eth_addr g_sMACAddr = +{ + { + ENET_MAC_ADDR0, + ENET_MAC_ADDR1, + ENET_MAC_ADDR2, + ENET_MAC_ADDR3, + ENET_MAC_ADDR4, + ENET_MAC_ADDR5 + } +}; +#else +static struct uip_eth_addr g_sMACAddr; +#endif + +//***************************************************************************** +// +// The number of SysTick interrupts since the start of the boot loader. +// +//***************************************************************************** +static uint32_t g_ui32Ticks; + +//***************************************************************************** +// +// The seed for the random number generator. +// +//***************************************************************************** +static uint32_t g_ui32RandomSeed; + +//***************************************************************************** +// +// The number of milliseconds since the last call to uip_udp_periodic(). +// +//***************************************************************************** +static volatile uint32_t g_ui32PeriodicTimer; + +//***************************************************************************** +// +// The number of milliseconds since the last call to uip_arp_timer(). +// +//***************************************************************************** +static volatile uint32_t g_ui32ARPTimer; + +//***************************************************************************** +// +// The transaction ID of the most recently sent out BOOTP request. +// +//***************************************************************************** +static uint32_t g_ui32XID; + +//***************************************************************************** +// +// The state for the proto-thread that handles the BOOTP process. +// +//***************************************************************************** +static struct pt g_sThread; + +//***************************************************************************** +// +// The amount of time to wait for a BOOTP reply before sending out a new BOOTP +// request. +// +//***************************************************************************** +static uint32_t g_ui32Delay; + +//***************************************************************************** +// +// The target time (relative to g_ui32Ticks) when the next timeout occurs. +// +//***************************************************************************** +static uint32_t g_ui32Target; + +//***************************************************************************** +// +// The IP address of the TFTP server. +// +//***************************************************************************** +static uip_ipaddr_t g_sServerAddr; + +//***************************************************************************** +// +// The name of the file to be read from the TFTP server. +// +//***************************************************************************** +static char g_pcFilename[128]; + +//***************************************************************************** +// +// The end of flash. If there is not a reserved block at the end of flash, +// this is the real end of flash. If there is a reserved block, this is the +// start of the reserved block (i.e. the virtual end of flash). +// +//***************************************************************************** +static uint32_t g_ui32FlashEnd; + +//***************************************************************************** +// +// The current block being read from the TFTP server. +// +//***************************************************************************** +static uint32_t g_ui32TFTPBlock; + +//***************************************************************************** +// +// The number of TFTP retries. +// +//***************************************************************************** +static uint32_t g_ui32TFTPRetries; + +//***************************************************************************** +// +// The UDP socket used to communicate with the BOOTP and TFTP servers (in +// sequence). +// +//***************************************************************************** +struct uip_udp_conn *g_pConn; + +//***************************************************************************** +// +// The current link status. +// +//***************************************************************************** +static uint32_t g_ui32Link; + +//***************************************************************************** +// +// Ethernet DMA descriptors. +// +// Although uIP uses a single buffer, the MAC hardware needs a minimum of +// 3 receive descriptors to operate. +// +//***************************************************************************** +#define NUM_TX_DESCRIPTORS 3 +#define NUM_RX_DESCRIPTORS 3 +tEMACDMADescriptor g_psRxDescriptor[NUM_TX_DESCRIPTORS]; +tEMACDMADescriptor g_psTxDescriptor[NUM_RX_DESCRIPTORS]; +uint32_t g_ui32RxDescIndex; +uint32_t g_ui32TxDescIndex; + +//***************************************************************************** +// +// Transmit and receive buffers. +// +//***************************************************************************** +#define RX_BUFFER_SIZE 1536 +#define TX_BUFFER_SIZE 1536 +uint8_t g_pui8RxBuffer[RX_BUFFER_SIZE]; +uint8_t g_pui8TxBuffer[TX_BUFFER_SIZE]; + +//***************************************************************************** +// +//! Handles the SysTick interrupt. +//! +//! This function is called when the SysTick interrupt occurs. It simply +//! keeps a running count of interrupts, used as a time basis for the BOOTP and +//! TFTP protocols. +//! +//! \return None. +// +//***************************************************************************** +void +SysTickIntHandler(void) +{ + // + // Increment the tick count. + // + g_ui32Ticks++; + g_ui32PeriodicTimer += SYSTICKMS; + g_ui32ARPTimer += SYSTICKMS; +} + +//***************************************************************************** +// +//! Computes a new random number. +//! +//! This function computes a new pseudo-random number, using a linear +//! congruence random number generator. Note that if the entire 32-bits of the +//! produced random number are not being used, the upper N bits should be used +//! instead of the lower N bits as they are much more random (for example, use +//! ``RandomNumber() >> 28'' instead of ``RandomNumber() & 15''). +//! +//! \return Returns a 32-bit pseudo-random number. +// +//***************************************************************************** +static uint32_t +RandomNumber(void) +{ + // + // Generate a new pseudo-random number with a linear congruence random + // number generator. This new random number becomes the seed for the next + // random number. + // + g_ui32RandomSeed = (g_ui32RandomSeed * 1664525) + 1013904223; + + // + // Return the new random number. + // + return(g_ui32RandomSeed); +} + +//***************************************************************************** +// +// Read a packet from the DMA receive buffer into the uIP packet buffer. +// +//***************************************************************************** +static int32_t +PacketReceive(uint8_t *pui8Buf, int32_t i32BufLen) +{ + int_fast32_t i32FrameLen, i32Loop; + + // + // By default, we assume we got a bad frame. + // + i32FrameLen = 0; + + // + // See if the receive descriptor contains a valid frame. Look for a + // descriptor error, indicating that the incoming packet was truncated or, + // if this is the last frame in a packet, the receive error bit. + // + if(!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & + DES0_RX_STAT_ERR)) + { + // + // We have a valid frame so copy the content to the supplied buffer. + // First check that the "last descriptor" flag is set. We sized the + // receive buffer such that it can always hold a valid frame so this + // flag should never be clear at this point but... + // + if(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & + DES0_RX_STAT_LAST_DESC) + { + i32FrameLen = + ((g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & + DES0_RX_STAT_FRAME_LENGTH_M) >> + DES0_RX_STAT_FRAME_LENGTH_S); + + // + // Sanity check. This shouldn't be required since we sized the uIP + // buffer such that it's the same size as the DMA receive buffer + // but, just in case... + // + if(i32FrameLen > i32BufLen) + { + i32FrameLen = i32BufLen; + } + + // + // Copy the data from the DMA receive buffer into the provided + // frame buffer. + // + for(i32Loop = 0; i32Loop < i32FrameLen; i32Loop++) + { + pui8Buf[i32Loop] = g_pui8RxBuffer[i32Loop]; + } + } + } + + // + // Move on to the next descriptor in the chain. + // + g_ui32RxDescIndex++; + if(g_ui32RxDescIndex == NUM_RX_DESCRIPTORS) + { + g_ui32RxDescIndex = 0; + } + + // + // Mark the next descriptor in the ring as available for the receiver to + // write into. + // + g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus = DES0_RX_CTRL_OWN; + + // + // Return the Frame Length + // + return(i32FrameLen); +} + +//***************************************************************************** +// +// Transmit a packet from the supplied buffer. +// +//***************************************************************************** +static int32_t +PacketTransmit(uint8_t *pui8Buf, int32_t i32BufLen) +{ + int_fast32_t i32Loop; + + // + // Wait for the previous packet to be transmitted. + // + while(g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus & + DES0_TX_CTRL_OWN) + { + } + + // + // Check that we're not going to overflow the transmit buffer. This + // shouldn't be necessary since the uIP buffer is smaller than our DMA + // transmit buffer but, just in case... + // + if(i32BufLen > TX_BUFFER_SIZE) + { + i32BufLen = TX_BUFFER_SIZE; + } + + // + // Copy the packet data into the transmit buffer. + // + for(i32Loop = 0; i32Loop < i32BufLen; i32Loop++) + { + g_pui8TxBuffer[i32Loop] = pui8Buf[i32Loop]; + } + + // + // Move to the next descriptor. + // + g_ui32TxDescIndex++; + if(g_ui32TxDescIndex == NUM_TX_DESCRIPTORS) + { + g_ui32TxDescIndex = 0; + } + + // + // Fill in the packet size and tell the transmitter to start work. + // + g_psTxDescriptor[g_ui32TxDescIndex].ui32Count = (uint32_t)i32BufLen; + g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus = + (DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG | + DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_IP_ALL_CKHSUMS | + DES0_TX_CTRL_CHAINED | DES0_TX_CTRL_OWN); + + // + // Tell the DMA to reacquire the descriptor now that we've filled it in. + // + ROM_EMACTxDMAPollDemand(EMAC0_BASE); + + // + // Return the number of bytes sent. + // + return(i32BufLen); +} + +//***************************************************************************** +// +//! Constructs and sends a BOOTP request packet. +//! +//! This function constructs a BOOTP request packet and sends it as a broadcast +//! message to the network. +//! +//! \return None. +// +//***************************************************************************** +static void +SendBOOTPRequest(void) +{ + uint8_t *pui8Packet = (uint8_t *)uip_appdata; + tBOOTPPacket *psBOOTP = (tBOOTPPacket *)uip_appdata; + uint32_t ui32Idx; + + // + // Zero fill the BOOTP request packet. + // + for(ui32Idx = 0; ui32Idx < sizeof(tBOOTPPacket); ui32Idx++) + { + pui8Packet[ui32Idx] = 0; + } + + // + // Construct a BOOTP request. + // + psBOOTP->ui8Op = BOOTP_REQUEST; + + // + // Set the hardware type to Ethernet. + // + psBOOTP->ui8HType = 0x01; + + // + // Set the hardware address length to 6. + // + psBOOTP->ui8HLen = 0x06; + + // + // Choose a random number for the transaction ID. + // + psBOOTP->ui32XID = g_ui32XID = RandomNumber(); + + // + // Set the number of seconds since we started. + // + psBOOTP->ui16Secs = HTONS(g_ui32Ticks / SYSTICKHZ); + + // + // Fill in the Ethernet MAC address. + // + for(ui32Idx = 0; ui32Idx < 6; ui32Idx++) + { + psBOOTP->pui8CHAddr[ui32Idx] = g_sMACAddr.addr[ui32Idx]; + } + + // + // Set the server name if defined. + // +#ifdef ENET_BOOTP_SERVER + for(ui32Idx = 0; + (psBOOTP->pcSName[ui32Idx] = ENET_BOOTP_SERVER[ui32Idx]) != 0; + ui32Idx++) + { + } +#endif + + // + // Send the BOOTP request packet. + // + uip_udp_send(sizeof(tBOOTPPacket)); +} + +//***************************************************************************** +// +//! Parses a packet checking for a BOOTP reply message. +//! +//! This function parses a packet to determine if it is a BOOTP reply to our +//! currently outstanding BOOTP request. If a valid reply is found, the +//! appropriate information from the packet is extracted and saved. +//! +//! \return Returns 1 if a valid BOOTP reply message was found and 0 otherwise. +// +//***************************************************************************** +static uint32_t +ParseBOOTPReply(void) +{ + tBOOTPPacket *psBOOTP = (tBOOTPPacket *)uip_appdata; + uint32_t ui32Idx; + + // + // See if this is a reply for our current BOOTP request. + // + if((psBOOTP->ui8Op != BOOTP_REPLY) || + (psBOOTP->ui32XID != g_ui32XID) || + (*(uint32_t *)psBOOTP->pui8CHAddr != *(uint32_t *)g_sMACAddr.addr) || + (*(uint16_t *)(psBOOTP->pui8CHAddr + 4) != + *(uint16_t *)(g_sMACAddr.addr + 4))) + { + return(0); + } + + // + // Extract our IP address from the response. + // + *((uint32_t *)(void *)(&uip_hostaddr)) = psBOOTP->ui32YIAddr; + + // + // Extract the server address from the response. + // + *((uint32_t *)(void *)(&g_sServerAddr)) = psBOOTP->ui32SIAddr; + + // + // Save the boot file name. + // + for(ui32Idx = 0; + ((g_pcFilename[ui32Idx] = psBOOTP->pcFile[ui32Idx]) != 0) && + (ui32Idx < (sizeof(g_pcFilename) - 1)); + ui32Idx++) + { + } + g_pcFilename[ui32Idx] = 0; + + // + // A valid BOOTP reply was found and decoded. + // + return(1); +} + + +//***************************************************************************** +// +//! Constructs and sends a TFTP error packet. +//! +//! This function constructs a TFTP read request packet (RRQ) and sends it to +//! the server. +//! +//! \return None. +// +//***************************************************************************** +static void +SendTFTPError(uint16_t ui16Error, char *pcString) +{ + uint8_t *pui8Packet = (uint8_t *)uip_appdata; + int32_t i32Len; + + pui8Packet[0] = (TFTP_ERROR >> 8) & 0xff; + pui8Packet[1] = TFTP_ERROR & 0xff; + pui8Packet[2] = (ui16Error >> 8) & 0xFF; + pui8Packet[3] = ui16Error & 0xFF; + + // + // Get ready to copy the error string. + // + i32Len = 4; + pui8Packet += 4; + + // + // Copy as much of the string as we can fit. + // + while((i32Len < (UIP_APPDATA_SIZE - 1)) && *pcString) + { + *pui8Packet++ = *pcString++; + i32Len++; + } + + // + // Write the terminating 0. + // + *pui8Packet = (uint8_t)0; + + // + // Send the error packet. + // + uip_udp_send(i32Len + 1); +} + +//***************************************************************************** +// +//! Constructs and sends a TFTP read packet. +//! +//! This function constructs a TFTP read request packet (RRQ) and sends it to +//! the server. +//! +//! \return None. +// +//***************************************************************************** +static void +SendTFTPGet(void) +{ + uint8_t *pui8Packet = (uint8_t *)uip_appdata; + uint32_t ui32Idx; + char *pcFilename; + + // + // The TFTP RRQ packet should be sent to the TFTP server port. + // + g_pConn->rport = HTONS(TFTP_PORT); + + // + // Set the TFTP packet opcode to RRQ. + // + pui8Packet[0] = (TFTP_RRQ >> 8) & 0xff; + pui8Packet[1] = TFTP_RRQ & 0xff; + + // + // Copy the file name into the RRQ packet. + // + for(ui32Idx = 2, pcFilename = g_pcFilename; + (pui8Packet[ui32Idx++] = *pcFilename++) != 0; ) + { + } + + // + // Set the transfer mode to binary. + // + for(pcFilename = "octet"; (pui8Packet[ui32Idx++] = *pcFilename++) != 0; ) + { + } + + // + // Send the TFTP read packet. + // + uip_udp_send(ui32Idx); +} + +//***************************************************************************** +// +//! Parses a packet checking for a TFTP data packet. +//! +//! This function parses a packet to determine if it is a TFTP data packet for +//! out current TFTP transfer. If a valid packet is found, the contents of the +//! packet are programmed into flash. +//! +//! \return Returns 1 if this packet was the last packet of the TFTP data +//! transfer and 0 otherwise. +// +//***************************************************************************** +static uint32_t +ParseTFTPData(void) +{ + uint8_t *pui8Packet = (uint8_t *)uip_appdata; + uint32_t ui32FlashAddr; + uint32_t ui32Idx; + + // + // See if this is a TFTP data packet. + // + if((pui8Packet[0] != ((TFTP_DATA >> 8) && 0xff)) || + (pui8Packet[1] != (TFTP_DATA & 0xff))) + { + return(0); + } + + // + // If the remote port on our connection is still the TFTP server port (i.e. + // this is the first data packet), then copy the transaction ID for the + // TFTP data connection into our connection. This will ensure that our + // response will be sent to the correct port. + // + if(g_pConn->rport == HTONS(TFTP_PORT)) + { + g_pConn->rport = + ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcport; + } + + // + // See if this is the correct data packet. + // + if((pui8Packet[2] != ((g_ui32TFTPBlock >> 8) & 0xff)) || + (pui8Packet[3] != (g_ui32TFTPBlock & 0xff))) + { + // + // Since the wrong data packet was sent, resend the ACK for it since + // we've already processed it. + // + pui8Packet[0] = (TFTP_ACK >> 8) & 0xff; + pui8Packet[1] = TFTP_ACK & 0xff; + uip_udp_send(4); + + // + // Ignore this packet. + // + return(0); + } + + // + // What address are we about to program to? + // + ui32FlashAddr = + ((g_ui32TFTPBlock - 1) * TFTP_BLOCK_SIZE) + APP_START_ADDRESS; + + // + // Do not program this data into flash if it is beyond the end of flash. + // + if(ui32FlashAddr < g_ui32FlashEnd) + { + // + // If this is the first block and we have been provided with a start + // hook function, call it here to indicate that we are about to begin + // flashing a new image. + // +#ifdef BL_START_FN_HOOK + if(g_ui32TFTPBlock == 1) + { + BL_START_FN_HOOK(); + } +#endif + + // + // Clear any flash error indicator. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // If this is the first data packet and code protection is enabled, + // then erase the entire flash. + // +#ifdef FLASH_CODE_PROTECTION + if(g_ui32TFTPBlock == 1) + { + // + // Loop through the pages in the flash, excluding the pages that + // contain the boot loader and the optional reserved space. + // + for(ui32Idx = APP_START_ADDRESS; ui32Idx < g_ui32FlashEnd; + ui32Idx += FLASH_PAGE_SIZE) + { + // + // Erase this block of the flash. + // + BL_FLASH_ERASE_FN_HOOK((ui32Idx); + } + } +#else + // + // Flash code protection is not enabled, so see if the data in this + // packet will be programmed to the beginning of a flash block. We + // assume that the flash block size is always a multiple of 1KB so, + // since each TFTP packet is 512 bytes and that the start must always + // be on a flash page boundary, we can be sure that we will hit the + // start of each page as we receive packets. + // + if(!(ui32FlashAddr & (FLASH_PAGE_SIZE - 1))) + { + // + // Erase this block of the flash. + // + BL_FLASH_ERASE_FN_HOOK(ui32FlashAddr); + } +#endif + + // + // Decrypt the data if required. + // +#ifdef BL_DECRYPT_FN_HOOK + BL_DECRYPT_FN_HOOK(pui8Packet + 4, uip_len - 4); +#endif + + // + // Program this block of data into flash. + // + BL_FLASH_PROGRAM_FN_HOOK(ui32FlashAddr, (pui8Packet + 4), + (uip_len - 4)); + + // + // If a progress reporting hook function has been provided, call it + // here. The TFTP protocol doesn't let us know how large the image is + // before it starts the transfer so we pass 0 as the ui32Total + // parameter to indicate this. + // +#ifdef BL_PROGRESS_FN_HOOK + BL_PROGRESS_FN_HOOK(((ui32FlashAddr - APP_START_ADDRESS) + + (uip_len - 4)), 0); +#endif + } + + // + // Increment to the next block. + // + g_ui32TFTPBlock++; + + // + // Save the packet length. + // + ui32Idx = uip_len; + + // + // Did we see any error? + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + // + // Yes - send back an error packet. + // + SendTFTPError(2, "Error programming flash."); + } + else + { + // + // No errors reported so construct an ACK packet. The block number + // field is already correct, so it does not need to be set. + // + pui8Packet[0] = (TFTP_ACK >> 8) & 0xff; + pui8Packet[1] = TFTP_ACK & 0xff; + + // + // Send the ACK packet to the TFTP server. + // + uip_udp_send(4); + } + + // + // If the packet was shorter than TFTP_BLOCK_SIZE bytes then this was the + // last packet in the file. + // + if(ui32Idx != (TFTP_BLOCK_SIZE + 4)) + { + // + // If an end signal hook function has been provided, call it here. + // +#ifdef BL_END_FN_HOOK + BL_END_FN_HOOK(); +#endif + return(1); + } + // + // There is more data to be read. + // + return(0); +} + +uint16_t +LOCAL_EMACPHYRead(uint32_t ui32Base, uint8_t ui8PhyAddr, uint8_t ui8RegAddr) +{ + + // + // Make sure the MII is idle. + // + while(HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB) + { + } + + // + // Tell the MAC to read the given PHY register. + // + HWREG(ui32Base + EMAC_O_MIIADDR) = + ((HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_CR_M) | + (ui8RegAddr << EMAC_MIIADDR_MII_S) | + (ui8PhyAddr << EMAC_MIIADDR_PLA_S) | EMAC_MIIADDR_MIIB); + + // + // Wait for the read to complete. + // + while(HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB) + { + } + + // + // Return the result. + // + return(HWREG(ui32Base + EMAC_O_MIIDATA) & EMAC_MIIDATA_DATA_M); +} + +//***************************************************************************** +// +//! Handles the BOOTP process. +//! +//! This function contains the proto-thread for handling the BOOTP process. It +//! first communicates with the BOOTP server to get its boot parameters (IP +//! address, server address, and file name), then it communicates with the TFTP +//! server on the specified server to read the firmware image file. +//! +//! \return None. +// +//***************************************************************************** +#ifdef DOXYGEN +char +BOOTPThread(void) +#else +PT_THREAD(BOOTPThread(void)) +#endif +{ + // + // Begin the proto-thread. + // + PT_BEGIN(&g_sThread); + +wait_for_link: + PT_WAIT_UNTIL(&g_sThread, + (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & + EPHY_BMSR_LINKSTAT) != 0); + + // + // Reset the host address. + // + *((uint32_t *)(void *)(&uip_hostaddr)) = 0; + + // + // Re-bind the UDP socket for sending requests to the BOOTP server. + // + uip_udp_remove(g_pConn); + *((uint32_t *)(void *)(&g_sServerAddr)) = 0xffffffff; + uip_udp_new(&g_sServerAddr, HTONS(BOOTP_SERVER_PORT)); + uip_udp_bind(g_pConn, HTONS(BOOTP_CLIENT_PORT)); + + // + // Set the initial delay between BOOTP requests to 1 second. + // + g_ui32Delay = SYSTICKHZ; + + // + // Loop forever. This loop is explicitly exited when a valid BOOTP reply + // is received. + // + while(1) + { + // + // Send a BOOTP request. + // + SendBOOTPRequest(); + + // + // Set the amount of time to wait for the BOOTP reply message. + // + g_ui32Target = g_ui32Ticks + g_ui32Delay; + + // + // Wait until a packet is received or the timeout has occurred. + // +wait_for_bootp_reply: + PT_WAIT_UNTIL(&g_sThread, + ((g_ui32Link = (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & + EPHY_BMSR_LINKSTAT)) == 0) || + uip_newdata() || (g_ui32Ticks > g_ui32Target)); + + // + // If the link has been lost, go back to waiting for a link. + // + if(g_ui32Link == 0) + { + goto wait_for_link; + } + + // + // See if a packet has been received. + // + if(uip_newdata()) + { + // + // Clear the new data flag so that this packet will only be + // examined one time. + // + uip_flags &= ~(UIP_NEWDATA); + + // + // See if this is a BOOTP reply. + // + if(ParseBOOTPReply() == 1) + { + break; + } + + // + // This was not a BOOTP reply packet, so go back to waiting. + // + goto wait_for_bootp_reply; + } + + // + // If the delay between BOOTP requests is less than 60 seconds, double + // the delay time. This avoids constantly slamming the network with + // requests. + // + if(g_ui32Delay < (60 * SYSTICKHZ)) + { + g_ui32Delay *= 2; + } + } + + // + // Reconfigure the UDP socket to target the TFTP port on the server. + // + uip_ipaddr_copy(&g_pConn->ripaddr, g_sServerAddr); + uip_udp_bind(g_pConn, HTONS(13633)); + + // + // Send a TFTP read request. + // + SendTFTPGet(); + + // + // Since the first TFTP read request will result in an ARP request, delay + // for just a bit and then re-issue the TFTP read request. + // + PT_YIELD(&g_sThread); + + // + // Resend the TFTP read request. If the ARP request has already been + // answered, this will go out as is and avoid the two second timeout below. + // + SendTFTPGet(); + + // + // Start the TFTP transfer from block one. + // + g_ui32TFTPBlock = 1; + + // + // Set the number of TFTP retries to zero. + // + g_ui32TFTPRetries = 0; + + // + // Loop forever. This loop is explicitly exited when the TFTP transfer has + // completed. + // + while(1) + { + // + // Set the amount of time to wait for the TFTP data packet. + // + g_ui32Target = g_ui32Ticks + (SYSTICKHZ * 4); + + // + // Wait until a packet is received or the timeout has occurred. + // + PT_WAIT_UNTIL(&g_sThread, + ((g_ui32Link = (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & + EPHY_BMSR_LINKSTAT)) == 0) || + uip_newdata() || (g_ui32Ticks > g_ui32Target)); + + // + // If the link has been lost, go back to waiting for a link. + // + if(g_ui32Link == 0) + { + goto wait_for_link; + } + + // + // See if a packet has been received. + // + if(uip_newdata()) + { + // + // Clear the new data flag so that this packet will only be + // examined one time. + // + uip_flags &= ~(UIP_NEWDATA); + + // + // See if this is a TFTP data packet. + // + if(ParseTFTPData() == 1) + { + break; + } + } + else if(g_ui32TFTPRetries < 3) + { + // + // The transfer timed out, so send a new TFTP read request. + // + SendTFTPGet(); + + // + // Start the TFTP transfer from block one. + // + g_ui32TFTPBlock = 1; + + // + // Increment the count of TFTP retries. + // + g_ui32TFTPRetries++; + } + else + { + // + // The TFTP transfer failed after three retries, so start over. + // + goto wait_for_link; + } + } + // + // Wait for the last packet to be transmitted. + // + while(g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus & + DES0_TX_CTRL_OWN) + { + } + + // + // Wait for a bit to make sure that the final ACK packet is transmitted. + // + g_ui32Target = g_ui32Ticks + (SYSTICKHZ / 4); + while(g_ui32Ticks < g_ui32Target) + { + PT_YIELD(&g_sThread); + } + + // + // Perform a software reset request. This will cause the microcontroller + // to reset; no further code will be executed. + // + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; + + // + // The microcontroller should have reset, so this should never be reached. + // Just in case, loop forever. + // + while(1) + { + } + + // + // End the proto-thread. + // + PT_END(&g_sThread); +} + +static void +LOCAL_EMACPHYConfigSet(uint32_t ui32Base, uint32_t ui32Config) +{ + // + // Write the Ethernet PHY configuration to the peripheral configuration + // register. + // + HWREG(ui32Base + EMAC_O_PC) = ui32Config; + + // + // If using the internal PHY, reset it to ensure that new configuration is + // latched there. + // + if((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_INTERNAL) + { + ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0); + while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0)) + { + // + // Wait for the PHY reset to complete. + // + } + + // + // Delay a bit longer to ensure that the PHY reset has completed. + // + ROM_SysCtlDelay(1000); + } + + // + // If using an external RMII PHY, we must set 2 bits in the Ethernet MAC + // Clock Configuration Register. + // + if((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_EXTERNAL_RMII) + { + // + // Select and enable the external clock from the RMII PHY. + // + HWREG(EMAC0_BASE + EMAC_O_CC) |= EMAC_CC_CLKEN; + } + else + { + // + // Disable the external clock. + // + HWREG(EMAC0_BASE + EMAC_O_CC) &= ~EMAC_CC_CLKEN; + } + + // + // Reset the MAC regardless of whether the PHY connection changed or not. + // + ROM_EMACReset(EMAC0_BASE); + + ROM_SysCtlDelay(1000); +} + +//***************************************************************************** +// +//! Reconfigures the Ethernet controller. +//! +//! \param ui32Clock is the system clock frequency. +//! +//! This function reconfigures the Ethernet controller, preparing it for use by +//! the boot loader. This performs the steps common between the direct +//! invocation of the boot loader and the application invocation of the boot +//! loader. +//! +//! \return None. +// +//***************************************************************************** +void +EnetReconfig(uint32_t ui32Clock) +{ + uip_ipaddr_t sAddr; + uint32_t ui32Loop; + uint32_t ui32User0, ui32User1; + + // + // Configure for use with the internal PHY. + // + LOCAL_EMACPHYConfigSet(EMAC0_BASE, + (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | + EMAC_PHY_AN_100B_T_FULL_DUPLEX)); + + + // + // Reset the MAC. + // + ROM_EMACReset(EMAC0_BASE); + + // + // Initialize the MAC and set the DMA mode. + // + ROM_EMACInit(EMAC0_BASE, ui32Clock, + EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4, 0); + + // + // Get the MAC address from the flash user registers. If it has not been + // programmed, then use the boot loader default MAC address. + // + ROM_FlashUserGet(&ui32User0, &ui32User1); + if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff)) + { + // + // MAC address has not been programmed, use default. + // + g_sMACAddr.addr[0] = 0x00; + g_sMACAddr.addr[1] = 0x1a; + g_sMACAddr.addr[2] = 0xb6; + g_sMACAddr.addr[3] = 0x00; + g_sMACAddr.addr[4] = 0x64; + g_sMACAddr.addr[5] = 0x00; + } + else + { + g_sMACAddr.addr[0] = ui32User0 & 0xff; + g_sMACAddr.addr[1] = (ui32User0 >> 8) & 0xff; + g_sMACAddr.addr[2] = (ui32User0 >> 16) & 0xff; + g_sMACAddr.addr[3] = ui32User1 & 0xff; + g_sMACAddr.addr[4] = (ui32User1 >> 8) & 0xff; + g_sMACAddr.addr[5] = (ui32User1 >> 16) & 0xff; + } + + // + // Set MAC configuration options. + // + ROM_EMACConfigSet(EMAC0_BASE, + (EMAC_CONFIG_FULL_DUPLEX | EMAC_CONFIG_CHECKSUM_OFFLOAD | + EMAC_CONFIG_7BYTE_PREAMBLE | EMAC_CONFIG_IF_GAP_96BITS | + EMAC_CONFIG_USE_MACADDR0 | EMAC_CONFIG_SA_FROM_DESCRIPTOR | + EMAC_CONFIG_BO_LIMIT_1024), + (EMAC_MODE_RX_STORE_FORWARD | EMAC_MODE_TX_STORE_FORWARD | + EMAC_MODE_TX_THRESHOLD_64_BYTES | + EMAC_MODE_RX_THRESHOLD_64_BYTES), 0); + + // + // Initialize each of the transmit descriptors. Note that we leave the OWN + // bit clear here since we have not set up any transmissions yet. + // + for(ui32Loop = 0; ui32Loop < NUM_TX_DESCRIPTORS; ui32Loop++) + { + g_psTxDescriptor[ui32Loop].ui32Count = + (DES1_TX_CTRL_SADDR_INSERT | + (TX_BUFFER_SIZE << DES1_TX_CTRL_BUFF1_SIZE_S)); + g_psTxDescriptor[ui32Loop].pvBuffer1 = g_pui8TxBuffer; + g_psTxDescriptor[ui32Loop].DES3.pLink = + (ui32Loop == (NUM_TX_DESCRIPTORS - 1)) ? + g_psTxDescriptor : &g_psTxDescriptor[ui32Loop + 1]; + g_psTxDescriptor[ui32Loop].ui32CtrlStatus = + (DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG | + DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_CHAINED | + DES0_TX_CTRL_IP_ALL_CKHSUMS); + } + + // + // Initialize each of the receive descriptors. We clear the OWN bit here + // to make sure that the receiver doesn't start writing anything + // immediately. + // + for(ui32Loop = 0; ui32Loop < NUM_RX_DESCRIPTORS; ui32Loop++) + { + g_psRxDescriptor[ui32Loop].ui32CtrlStatus = 0; + g_psRxDescriptor[ui32Loop].ui32Count = + (DES1_RX_CTRL_CHAINED | + (RX_BUFFER_SIZE << DES1_RX_CTRL_BUFF1_SIZE_S)); + g_psRxDescriptor[ui32Loop].pvBuffer1 = g_pui8RxBuffer; + g_psRxDescriptor[ui32Loop].DES3.pLink = + (ui32Loop == (NUM_RX_DESCRIPTORS - 1)) ? + g_psRxDescriptor : &g_psRxDescriptor[ui32Loop + 1]; + } + + // + // Set the descriptor pointers in the hardware. + // + ROM_EMACRxDMADescriptorListSet(EMAC0_BASE, g_psRxDescriptor); + ROM_EMACTxDMADescriptorListSet(EMAC0_BASE, g_psTxDescriptor); + + // + // Start from the beginning of both descriptor chains. We actually set + // the transmit descriptor index to the last descriptor in the chain + // since it will be incremented before use and this means the first + // transmission we perform will use the correct descriptor. + // + g_ui32RxDescIndex = 0; + g_ui32TxDescIndex = NUM_TX_DESCRIPTORS - 1; + + // + // Program the MAC address. + // + ROM_EMACAddrSet(EMAC0_BASE, 0, g_sMACAddr.addr); + + // + // Wait for the link to become active. + // + while((ROM_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) & + EPHY_BMSR_LINKSTAT) == 0) + { + } + + // + // Set MAC filtering options. We receive all broadcast and multicast + // packets along with those addressed specifically for us. + // + ROM_EMACFrameFilterSet(EMAC0_BASE, (EMAC_FRMFILTER_SADDR | + EMAC_FRMFILTER_PASS_MULTICAST | + EMAC_FRMFILTER_PASS_NO_CTRL)); + + // + // Seed the random number generator from the MAC address. + // + g_ui32RandomSeed = *(uint32_t *)(g_sMACAddr.addr + 2); + + // + // Initialize the uIP stack. + // + uip_init(); + uip_arp_init(); + + // + // Set the MAC address. + // + uip_setethaddr(g_sMACAddr); + + // + // Initialize the proto-thread used by the BOOTP protocol handler. + // + PT_INIT(&g_sThread); + + // + // Create a UDP socket for sending requests to the BOOTP server. After the + // BOOTP portion of the protocol has been handled, this socket will be + // reused to communicate with the TFTP server. + // + *((uint32_t *)(void *)(&sAddr)) = 0xffffffff; + g_pConn = uip_udp_new(&sAddr, HTONS(BOOTP_SERVER_PORT)); + uip_udp_bind(g_pConn, HTONS(BOOTP_CLIENT_PORT)); + + // + // Enable the Ethernet MAC transmitter and receiver. + // + ROM_EMACTxEnable(EMAC0_BASE); + ROM_EMACRxEnable(EMAC0_BASE); + + // + // Mark the first receive descriptor as available to the DMA to start + // the receive processing. + // + g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus |= DES0_RX_CTRL_OWN; + + // + // Reset the counters that are incremented by SysTick. + // + g_ui32Ticks = 0; + g_ui32PeriodicTimer = 0; + g_ui32ARPTimer = 0; + + // + // Setup SysTick. + // + HWREG(NVIC_ST_RELOAD) = (ui32Clock / SYSTICKHZ) - 1; + HWREG(NVIC_ST_CTRL) = (NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | + NVIC_ST_CTRL_ENABLE); +} +//***************************************************************************** +// +//! Configures the Ethernet controller. +//! +//! This function configures the Ethernet controller, preparing it for use by +//! the boot loader. +//! +//! \return None. +// +//***************************************************************************** +void +ConfigureEnet(void) +{ + // + // Make sure the main oscillator is enabled because this is required by + // the PHY. The system must have a 25MHz crystal attached to the OSC + // pins. The SYSCTL_MOSC_HIGHFREQ parameter is used when the crystal + // frequency is 10MHz or higher. + // + HWREG(SYSCTL_MOSCCTL) = SYSCTL_MOSC_HIGHFREQ; + + // + // Delay while the main oscillator starts up. + // + Delay(5242880); + + MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | + SYSCTL_OSC_MAIN | + SYSCTL_USE_PLL | + SYSCTL_CFG_VCO_480), 120000000); + + +#ifdef ENET_ENABLE_LEDS + // + // PF1/PK4/PK6 are used for Ethernet LEDs. + // + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); + ROM_GPIOPinConfigure(GPIO_PF1_EN0LED2); + ROM_GPIOPinConfigure(GPIO_PK4_EN0LED0); + ROM_GPIOPinConfigure(GPIO_PK6_EN0LED1); + + // + // Make the pin(s) be peripheral controlled. + // + ROM_GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW); + ROM_GPIODirModeSet(GPIO_PORTK_BASE, GPIO_PIN_4|GPIO_PIN_6, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation. + // + ROM_GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); + ROM_GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_4|GPIO_PIN_6, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); +#endif + + // + // Enable and reset the Ethernet modules. + // + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0); + ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0); + ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0); + + while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0)) + { + } + +} + +//***************************************************************************** +// +//! Starts the update process via BOOTP. +//! +//! This function starts the Ethernet firmware update process. The BOOTP +//! (as defined by RFC951 at http://tools.ietf.org/html/rfc951) and TFTP (as +//! defined by RFC1350 at http://tools.ietf.org/html/rfc1350) protocols are +//! used to transfer the firmware image over Ethernet. +//! +//! \return Never returns. +// +//***************************************************************************** +void +UpdateBOOTP(void) +{ + // + // Get the size of flash. + // + g_ui32FlashEnd = ROM_SysCtlFlashSizeGet(); +#ifdef FLASH_RSVD_SPACE + g_ui32FlashEnd -= FLASH_RSVD_SPACE; +#endif + + // + // Perform the common Ethernet configuration. The frequency should + // match whatever the application sets the system clock. + // + EnetReconfig(120000000); + + // + // Main Application Loop. + // + while(1) + { + uint32_t ui32Temp; + + // + // See if there is a packet waiting to be read. + // + if(!(g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus & + DES0_RX_CTRL_OWN)) + { + // + // Read the packet from the Ethernet controller. + // + uip_len = PacketReceive(uip_buf, UIP_CONF_BUFFER_SIZE); + + // + // See if this is an IP packet. + // + if((uip_len != 0) && + (((struct uip_eth_hdr *)&uip_buf[0])->type == + HTONS(UIP_ETHTYPE_IP))) + { + // + // Update the ARP tables based on this packet. + // + uip_arp_ipin(); + + // + // Process this packet. + // + uip_input(); + + // + // See if the processing of this packet resulted in a packet to be + // sent. + // + if(uip_len > 0) + { + // + // Update the ARP tables based on the packet to be sent. + // + uip_arp_out(); + + // + // Send the packet. + // + PacketTransmit(uip_buf, uip_len); + + // + // Indicate that the packet has been sent. + // + uip_len = 0; + } + } + + // + // See if this is an ARP packet. + // + else if((uip_len != 0) && + (((struct uip_eth_hdr *)&uip_buf[0])->type == + HTONS(UIP_ETHTYPE_ARP))) + { + // + // Process this packet. + // + uip_arp_arpin(); + + // + // See if the processing of this packet resulted in a packet to be + // sent. + // + if(uip_len > 0) + { + // + // Send the packet. + // + PacketTransmit(uip_buf, uip_len); + + // + // Indicate that the packet has been sent. + // + uip_len = 0; + } + } + } + + // + // See if the periodic timer has expired. + // + if(g_ui32PeriodicTimer > UIP_PERIODIC_TIMER_MS) + { + // + // Reset the periodic timer. + // + g_ui32PeriodicTimer = 0; + + // + // Loop through the UDP connections. + // + for(ui32Temp = 0; ui32Temp < UIP_UDP_CONNS; ui32Temp++) + { + // + // Perform the periodic processing on this UDP connection. + // + uip_udp_periodic(ui32Temp); + + // + // See if the periodic processing of this connection resulted in a + // packet to be sent. + // + if(uip_len > 0) + { + // + // Update the ARP tables based on the packet to be sent. + // + uip_arp_out(); + + // + // Send the packet. + // + PacketTransmit(uip_buf, uip_len); + + // + // Indicate that the packet has been sent. + // + uip_len = 0; + } + } + } + + // + // See if the ARP timer has expired. + // + if(g_ui32ARPTimer > UIP_ARP_TIMER_MS) + { + // + // Reset the ARP timer. + // + g_ui32ARPTimer = 0; + + // + // Perform periodic processing on the ARP table. + // + uip_arp_timer(); + } + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..4461b9f8d4ceabfbc919a1aea4493d7d363c0ac2 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.c @@ -0,0 +1,230 @@ +//***************************************************************************** +// +// bl_flash.c - Flash programming functions used by the boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_types.h" +#include "inc/hw_flash.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_memmap.h" +#include "bl_config.h" +#include "boot_loader/bl_flash.h" + +//***************************************************************************** +// +//! Erases a single 1KB block of internal flash. +//! +//! \param ui32Address is the address of the block of flash to erase. +//! +//! This function erases a single 1KB block of the internal flash, blocking +//! until the erase has completed. +//! +//! \return None +// +//***************************************************************************** +void +BLInternalFlashErase(uint32_t ui32Address) +{ + // + // Erase this block of the flash. + // + HWREG(FLASH_FMA) = ui32Address; + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE; + + // + // Wait until the flash has been erased. + // + while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE) + { + } +} + +//***************************************************************************** +// +//! Programs a block of data at a given address in the internal flash. +//! +//! \param ui32DstAddr is the address of the first word to be programmed in +//! flash. +//! \param pui8SrcData is a pointer to the first byte to be programmed. +//! \param ui32Length is the number of bytes to program. This must be a +//! multiple of 4. +//! +//! This function writes a block of data to the internal flash at a given +//! address. Since the flash is written a word at a time, the data must be a +//! multiple of 4 bytes and the destination address, ui32DstAddr, must be on a +//! word boundary. +//! +//! \return None +// +//***************************************************************************** +void +BLInternalFlashProgram(uint32_t ui32DstAddr, uint8_t *pui8SrcData, + uint32_t ui32Length) +{ + uint32_t ui32Loop; + + for(ui32Loop = 0; ui32Loop < ui32Length; ui32Loop += 4) + { + // + // Program this word into flash. + // + HWREG(FLASH_FMA) = ui32DstAddr + ui32Loop; + HWREG(FLASH_FMD) = *(uint32_t *)(pui8SrcData + ui32Loop); + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE; + + // + // Wait until the flash has been programmed. + // + while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE) + { + } + } +} + +//***************************************************************************** +// +//! Returns the size of the internal flash in bytes. +//! +//! This function returns the total number of bytes of internal flash in the +//! current part. No adjustment is made for any sections reserved via +//! options defined in bl_config.h. +//! +//! \return Returns the total number of bytes of internal flash. +// +//***************************************************************************** +uint32_t +BLInternalFlashSizeGet(void) +{ +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + return(((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1) << 11); +#else + return(((HWREG(FLASH_FSIZE) & FLASH_FSIZE_SIZE_M) + 1) << 11); +#endif +} + +//***************************************************************************** +// +//! Checks whether a given start address is valid for a download. +//! +//! This function checks to determine whether the given address is a valid +//! download image start address given the options defined in bl_config.h. +//! +//! \return Returns non-zero if the address is valid or 0 otherwise. +// +//***************************************************************************** +uint32_t +BLInternalFlashStartAddrCheck(uint32_t ui32Addr, uint32_t ui32ImgSize) +{ + uint32_t ui32FlashSize; + + // + // Determine the size of the flash available on the part in use. + // +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + ui32FlashSize = ((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1) << 11; +#else + ui32FlashSize = ((HWREG(FLASH_FSIZE) & FLASH_FSIZE_SIZE_M) + 1) << 11; +#endif + + // + // If we are reserving space at the top of flash then this space is not + // available for application download but it is availble to be updated + // directly. + // +#ifdef FLASH_RSVD_SPACE + if((ui32FlashSize - FLASH_RSVD_SPACE) != ui32Addr) + { + ui32FlashSize -= FLASH_RSVD_SPACE; + } +#endif + + // + // Is the address we were passed a valid start address? We allow: + // + // 1. Address 0 if configured to update the boot loader. + // 2. The start of the reserved block if parameter space is reserved (to + // allow a download of the parameter block contents). + // 3. The application start address specified in bl_config.h. + // + // The function fails if the address is not one of these, if the image + // size is larger than the available space or if the address is not word + // aligned. + // + if(( +#ifdef ENABLE_BL_UPDATE + (ui32Addr != 0) && +#endif +#ifdef FLASH_RSVD_SPACE + (ui32Addr != (ui32FlashSize - FLASH_RSVD_SPACE)) && +#endif + (ui32Addr != APP_START_ADDRESS)) || + ((ui32Addr + ui32ImgSize) > ui32FlashSize) || ((ui32Addr & 3) != 0)) + { + return(0); + } + else + { + return(1); + } +} + +//***************************************************************************** +// +//! Checks whether a flash access violation occurred. +//! +//! This function checks whether an access violation error occurred during +//! the previous program or erase operation. +//! +//! \return Returns 0 if no error occurred or a non-zero value if an error was +//! reported. +// +//***************************************************************************** +void +BLInternalFlashErrorClear(void) +{ + // + // Clear the flash controller access interrupt. + // + HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC; +} + +//***************************************************************************** +// +//! Checks whether a flash access violation occurred. +//! +//! This function checks whether an access violation error occurred since the +//! last call to BLInternalFlashErrorClear(). +//! +//! \return Returns 0 if no error occurred or a non-zero value if an error was +//! reported. +// +//***************************************************************************** +uint32_t +BLInternalFlashErrorCheck(void) +{ + return(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS); +} diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..af091e6bd5c04a322c94a88aa32b9444f16662ab --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_flash.h @@ -0,0 +1,127 @@ +//***************************************************************************** +// +// bl_flash.h - Flash programming functions used by the boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_FLASH_H__ +#define __BL_FLASH_H__ + +#include "driverlib/rom.h" + +//***************************************************************************** +// +// Basic functions for erasing and programming internal flash. +// +//***************************************************************************** +extern void BLInternalFlashErase(uint32_t ui32Address); +extern void BLInternalFlashProgram(uint32_t ui32DstAddr, uint8_t *pui8SrcData, + uint32_t ui32Length); +extern uint32_t BLInternalFlashSizeGet(void); +extern uint32_t BLInternalFlashStartAddrCheck(uint32_t ui32Addr, + uint32_t ui32ImgSize); +extern uint32_t BLInternalFlashErrorCheck(void); +extern void BLInternalFlashErrorClear(void); + +//***************************************************************************** +// +// If the user has not specified which flash programming functions to use, +// default to the basic, internal flash functions on Sandstorm, Fury and +// DustDevil parts or the ROM-resident function for Tempest-class parts. +// +//***************************************************************************** +#ifndef BL_FLASH_ERASE_FN_HOOK +#define BL_FLASH_ERASE_FN_HOOK(ui32Address) \ + { \ + HWREG(FLASH_FMA) = (ui32Address); \ + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE; \ + while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE) \ + { \ + } \ + } +#else +extern void BL_FLASH_ERASE_FN_HOOK(uint32_t ui32Address); +#endif + +#ifndef BL_FLASH_PROGRAM_FN_HOOK +#ifdef ROM_FlashProgram +#define BL_FLASH_PROGRAM_FN_HOOK(ui32DstAddr, pui8SrcData, ui32Length) \ + ROM_FlashProgram((uint32_t *)pui8SrcData, ui32DstAddr, \ + (((ui32Length) + 3) & ~3)) +#else +#define BL_FLASH_PROGRAM_FN_HOOK(ui32DstAddr, pui8SrcData, ui32Length) \ + { \ + uint32_t ui32FlashProgLoop; \ + \ + for(ui32FlashProgLoop = 0; ui32FlashProgLoop < (ui32Length); \ + ui32FlashProgLoop += 4) \ + { \ + HWREG(FLASH_FMA) = (ui32DstAddr) + ui32FlashProgLoop; \ + HWREG(FLASH_FMD) = *(uint32_t *)((pui8SrcData) + \ + ui32FlashProgLoop); \ + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE; \ + while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE) \ + { \ + } \ + } \ + } +#endif +#else +extern uint32_t BL_FLASH_PROGRAM_FN_HOOK(uint32_t ui32DstAddr, + uint8_t *pui8SrcData, + uint32_t ui32Length); +#endif + +#ifndef BL_FLASH_CL_ERR_FN_HOOK +#define BL_FLASH_CL_ERR_FN_HOOK() HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC +#else +extern void BL_FLASH_CL_ERR_FN_HOOK(void); +#endif + +#ifndef BL_FLASH_ERROR_FN_HOOK +#define BL_FLASH_ERROR_FN_HOOK() (HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS) +#else +extern uint32_t BL_FLASH_ERROR_FN_HOOK(void); +#endif + +#ifndef BL_FLASH_SIZE_FN_HOOK +#define BL_FLASH_SIZE_FN_HOOK() \ + (((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1) << 11) +#else +extern uint32_t BL_FLASH_SIZE_FN_HOOK(void); +#endif + +#ifndef BL_FLASH_END_FN_HOOK +#define BL_FLASH_END_FN_HOOK() \ + (((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1) << 11) +#else +extern uint32_t BL_FLASH_END_FN_HOOK(void); +#endif + +#ifndef BL_FLASH_AD_CHECK_FN_HOOK +#define BL_FLASH_AD_CHECK_FN_HOOK(ui32Addr, ui32Size) \ + BLInternalFlashStartAddrCheck((ui32Addr), (ui32Size)) +#else +extern uint32_t BL_FLASH_AD_CHECK_FN_HOOK(uint32_t ui32Address, + uint32_t ui32Length); +#endif + +#endif // __BL_FLASH_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_hooks.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_hooks.h new file mode 100644 index 0000000000000000000000000000000000000000..e91cd510a08b51880fc4eff9632fe12dd3160afb --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_hooks.h @@ -0,0 +1,72 @@ +//***************************************************************************** +// +// bl_hooks.h - Definitions for the application-specific hook function. +// +// Copyright (c) 2009-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_HOOKS_H__ +#define __BL_HOOKS_H__ + +//***************************************************************************** +// +// Prototypes for any application-specific hook functions that are defined in +// bl_config.h. Note that the low level flash programming hooks are handled +// in bl_flash.h to allow us to define macros for internal flash programming +// in the normal case where no override functions are provided. +// +//***************************************************************************** +#ifdef BL_HW_INIT_FN_HOOK +extern void BL_HW_INIT_FN_HOOK(void); +#endif +#ifdef BL_INIT_FN_HOOK +extern void BL_INIT_FN_HOOK(void); +#endif +#ifdef BL_REINIT_FN_HOOK +extern void BL_REINIT_FN_HOOK(void); +#endif +#ifdef BL_START_FN_HOOK +extern void BL_START_FN_HOOK(void); +#endif +#ifdef BL_PROGRESS_FN_HOOK +extern void BL_PROGRESS_FN_HOOK(uint32_t ui32Completed, uint32_t ui32Total); +#endif +#ifdef BL_END_FN_HOOK +extern void BL_END_FN_HOOK(void); +#endif +#ifdef BL_DECRYPT_FN_HOOK +extern void BL_DECRYPT_FN_HOOK(uint8_t *pui8Buffer, uint32_t ui32Size); +#endif +#ifdef BL_CHECK_UPDATE_FN_HOOK +extern uint32_t BL_CHECK_UPDATE_FN_HOOK(void); +#endif + +//***************************************************************************** +// +// If ENABLE_DECRYPTION is defined but we don't have a hook function set for +// decryption, default to the previous behavior which calls the stub function +// DecryptData. +// +//***************************************************************************** +#if (defined ENABLE_DECRYPTION) && !(defined BL_DECRYPT_FN_HOOK) +#define BL_DECRYPT_FN_HOOK DecryptData +#endif + +#endif // __BL_HOOKS_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..1fafe9c1ad599d2576cb1aba3c986f307ba8d743 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.c @@ -0,0 +1,149 @@ +//***************************************************************************** +// +// bl_i2c.c - This file contains the function used to transfer data via the I2C +// port. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_gpio.h" +#include "inc/hw_i2c.h" +#include "inc/hw_memmap.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "bl_config.h" +#include "boot_loader/bl_i2c.h" + +//***************************************************************************** +// +//! \addtogroup bl_i2c_api +//! @{ +// +//***************************************************************************** +#if defined(I2C_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +//! Sends data over the I2C port. +//! +//! \param pui8Data is the buffer containing the data to write out to the I2C +//! port. +//! \param ui32Size is the number of bytes provided in \e pui8Data buffer that +//! will be written out to the I2C port. +//! +//! This function sends \e ui32Size bytes of data from the buffer pointed to by +//! \e pui8Data via the I2C port. The function will wait till the I2C Slave +//! port has been properly addressed by the I2C Master device before sending +//! the first byte. +//! +//! \return None. +// +//***************************************************************************** +void +I2CSend(const uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Transmit the number of bytes requested on the UART port. + // + while(ui32Size--) + { + // + // Wait for request to come in at slave. + // + while(!(HWREG(I2Cx_BASE + I2C_O_SCSR) & I2C_SCSR_TREQ)) + { + } + + // + // Send out the next byte. + // + HWREG(I2Cx_BASE + I2C_O_SDR) = *pui8Data++; + } +} + +//***************************************************************************** +// +//! Waits until all data has been transmitted by the I2C port. +//! +//! This function waits until all data written to the I2C port has been read by +//! the master. +//! +//! \return None. +// +//***************************************************************************** +void +I2CFlush(void) +{ + // + // Wait until the I2C bus is no longer busy, meaning that the last byte has + // been sent. + // + while(HWREG(I2Cx_BASE + I2C_O_MCS) & I2C_MCS_BUSBSY) + { + } +} + +//***************************************************************************** +// +//! Receives data over the I2C port. +//! +//! \param pui8Data is the buffer to read data into from the I2C port. +//! \param ui32Size is the number of bytes provided in the \e pui8Data buffer +//! that should be written with data from the I2C port. +//! +//! This function reads back \e ui32Size bytes of data from the I2C port, into +//! the buffer that is pointed to by \e pui8Data. This function will not +//! return until \e ui32Size number of bytes have been received. This function +//! will wait till the I2C Slave port has been properly addressed by the I2C +//! Master before reading the first byte of data from the I2C port. +//! +//! \return None. +// +//***************************************************************************** +void +I2CReceive(uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Send out the number of bytes requested. + // + while(ui32Size--) + { + // + // Wait until the slave has received the character. + // + while(!(HWREG(I2Cx_BASE + I2C_O_SCSR) & I2C_SCSR_RREQ)) + { + } + + // + // Receive a byte from the I2C. + // + *pui8Data++ = HWREG(I2Cx_BASE + I2C_O_SDR); + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..924fa6b8ff1a24250c757da3a522727fbe056702 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_i2c.h @@ -0,0 +1,122 @@ +//***************************************************************************** +// +// bl_i2c.h - Definitions for the I2C transport functions. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_I2C_H__ +#define __BL_I2C_H__ + +//***************************************************************************** +// +// This section maps the defines to default for I2C Boot Loader for legacy +// projects +// +//***************************************************************************** +#ifndef I2C_CLOCK_ENABLE +#define I2C_CLOCK_ENABLE SYSCTL_RCGCI2C_R0 +#endif + +#ifndef I2Cx_BASE +#define I2Cx_BASE I2C0_BASE +#endif + +#ifndef I2C_SCLPIN_CLOCK_ENABLE +#define I2C_SCLPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R1 +#endif + +#ifndef I2C_SCLPIN_BASE +#define I2C_SCLPIN_BASE GPIO_PORTB_BASE +#endif + +#ifndef I2C_SCLPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define I2C_SCLPIN_PCTL 0x2 +#else +#define I2C_SCLPIN_PCTL 0x3 +#endif +#endif + +#ifndef I2C_SCLPIN_POS +#define I2C_SCLPIN_POS 2 +#endif + +#ifndef I2C_SDAPIN_CLOCK_ENABLE +#define I2C_SDAPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R1 +#endif + +#ifndef I2C_SDAPIN_BASE +#define I2C_SDAPIN_BASE GPIO_PORTB_BASE +#endif + +#ifndef I2C_SDAPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define I2C_SDAPIN_PCTL 0x2 +#else +#define I2C_SDAPIN_PCTL 0x3 +#endif +#endif + +#ifndef I2C_SDAPIN_POS +#define I2C_SDAPIN_POS 3 +#endif + +//***************************************************************************** +// +// This defines the I2C clock pin that is being used by the boot loader. +// +//***************************************************************************** +#define I2C_CLK (1 << I2C_SCLPIN_POS) +#define I2C_CLK_PCTL (I2C_SCLPIN_PCTL << (4 * I2C_SCLPIN_POS)) + +//***************************************************************************** +// +// This defines the I2C data pin that is being used by the boot loader. +// +//***************************************************************************** +#define I2C_DATA (1 << I2C_SDAPIN_POS) +#define I2C_DATA_PCTL (I2C_SDAPIN_PCTL << (4 * I2C_SDAPIN_POS)) + +//***************************************************************************** +// +// I2C Transport APIs +// +//***************************************************************************** +extern void I2CSend(const uint8_t *pui8Data, uint32_t ui32Size); +extern void I2CReceive(uint8_t *pui8Data, uint32_t ui32Size); +extern void I2CFlush(void); + +//***************************************************************************** +// +// Define the transport functions if the I2C port is being used. +// +//***************************************************************************** +#ifdef I2C_ENABLE_UPDATE +#define SendData I2CSend +#define FlushData I2CFlush +#define ReceiveData I2CReceive +#endif + +#endif // __BL_I2C_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.icf b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.icf new file mode 100644 index 0000000000000000000000000000000000000000..a04ba77420c037ccee2c4f1ab896048c796fb387 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.icf @@ -0,0 +1,91 @@ +//***************************************************************************** +// +// bl_link.icf - Linker script for EW-ARM. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +// +// Define a memory region that covers the entire 4 GB addressible space of the +// processor. +// +define memory mem with size = 4G; + +// +// Define a region for the on-chip flash. +// +define region FLASH = mem:[from 0x00000000 to 0x0000ffff]; + +// +// Define a region for the on-chip SRAM. +// +define region SRAM = mem:[from 0x20000000 to 0x2000ffff]; + +// +// Indicate that the sections containing the boot loader code should be +// initialized by copying. +// +initialize manually with packing = none { section INTVEC }; +initialize manually with packing = none { section CODE }; +initialize manually with packing = none { section .text }; +initialize manually with packing = none { section .rodata }; +initialize manually with packing = none { section .data }; + +keep { section INTVEC }; +keep { section INTVEC_init }; + +// +// Indicate that the noinit values should be left alone. This includes the +// stack, which if initialized will destroy the return address from the +// initialization code, causing the processor to branch to zero and fault. +// +do not initialize { section .noinit }; + +// +// Indicate that the bss values should be left alone. This is required with +// newer versions of EWARM, without which, a compilation error is generated +// about a missing reference to the function that initializes the bss section. +// Note that the bootloader already initializes the bss section. +// +do not initialize { section .bss }; + +// +// Place the interrupt vectors at the start of flash/SRAM. +// +place at start of FLASH { readonly section INTVEC_init }; +place at start of SRAM { readwrite section INTVEC }; + +// +// Place the remainder of the read-only items into flash/SRAM. +// +place in FLASH { readonly section CODE_init }; +place in SRAM { readwrite section CODE }; +place in FLASH { readonly section .text_init }; +place in SRAM { readwrite section .text }; +place in FLASH { readonly section .rodata_init }; +place in SRAM { readwrite section .rodata }; +place in FLASH { readonly section .data_init }; +place in SRAM { readwrite section .data }; +place in FLASH { readonly }; + +// +// Place all read/write items into SRAM. +// +place in SRAM { readwrite }; diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.ld b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.ld new file mode 100644 index 0000000000000000000000000000000000000000..d0617dcb6f5be2180824c40ff33ef39d3fd6588b --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.ld @@ -0,0 +1,51 @@ +/****************************************************************************** + * + * bl_link.ld - Scatter file for Gnu tools + * + * Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. + * Software License Agreement + * + * Texas Instruments (TI) is supplying this software for use solely and + * exclusively on TI's microcontroller products. The software is owned by + * TI and/or its suppliers, and is protected under applicable copyright + * laws. You may not combine this software with "viral" open-source + * software in order to form a larger program. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. + * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT + * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY + * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL + * DAMAGES, FOR ANY REASON WHATSOEVER. + * + * This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. + * + *****************************************************************************/ + +SECTIONS +{ + .text 0x20000000 : AT (0x00000000) + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + _etext = .; + } + + .data 0x20000000 + SIZEOF(.text) : AT (SIZEOF(.text)) + { + _data = .; + *(.data*) + _edata = .; + } + + .bss 0x20000000 + SIZEOF(.text) + SIZEOF(.data) : + AT (ADDR(.data) + SIZEOF(.data)) + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } +} diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.sct b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.sct new file mode 100644 index 0000000000000000000000000000000000000000..2b02d69cff20f4da5c4a769ac2f401c60107d9da --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link.sct @@ -0,0 +1,45 @@ +;****************************************************************************** +; +; bl_link.sct - Scatter file for RV-MDK. +; +; Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +; Software License Agreement +; +; Texas Instruments (TI) is supplying this software for use solely and +; exclusively on TI's microcontroller products. The software is owned by +; TI and/or its suppliers, and is protected under applicable copyright +; laws. You may not combine this software with "viral" open-source +; software in order to form a larger program. +; +; THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +; NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +; NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +; CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +; DAMAGES, FOR ANY REASON WHATSOEVER. +; +; This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +; +;****************************************************************************** + +; +; The contents of this application reside in flash. +; +FLASH 0x00000000 0x00010000 +{ + ; + ; Place the vector table and reset handlers into flash. + ; + RESET 0x00000000 0x00010000 + { + *.o (RESET, +First) + } + + ; + ; Place everything else remaining into SRAM (RO, RW, and ZI) + ; + SRAM +0x20000000 0x00010000 + { + * (+RO, +RW, +ZI) + } +} diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link_ccs.cmd b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link_ccs.cmd new file mode 100644 index 0000000000000000000000000000000000000000..94e558bada9cb458a604ad5fd7af981640e894df --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_link_ccs.cmd @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * bl_link_ccs.cmd - CCS linker configuration file for boot loader. + * + * Copyright (c) 2009-2017 Texas Instruments Incorporated. All rights reserved. + * Software License Agreement + * + * Texas Instruments (TI) is supplying this software for use solely and + * exclusively on TI's microcontroller products. The software is owned by + * TI and/or its suppliers, and is protected under applicable copyright + * laws. You may not combine this software with "viral" open-source + * software in order to form a larger program. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. + * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT + * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY + * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL + * DAMAGES, FOR ANY REASON WHATSOEVER. + * + * This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. + * + *****************************************************************************/ + +--retain=Vectors + +/* The following command line options are set as part of the CCS project. */ +/* If you are building using the command line, or for some reason want to */ +/* define them here, you can uncomment and modify these lines as needed. */ +/* If you are using CCS for building, it is probably better to make any such */ +/* modifications in your CCS project and leave this file alone. */ +/* */ +/* --heap_size=0 */ +/* --stack_size=256 */ +/* --library=rtsv7M3_T_le_eabi.lib */ + +/* System memory map */ + +MEMORY +{ + FLASH (RX) : origin = 0x00000000, length = 0x00010000 + SRAM (RWX) : origin = 0x20000000, length = 0x00010000 +} + +/* Section allocation in memory */ + +SECTIONS +{ + GROUP + { + .intvecs + .text + .const + .data + } load = FLASH, run = 0x20000000, LOAD_START(init_load), RUN_START(init_run), SIZE(init_size) + + GROUP + { + .bss + .stack + } run = SRAM, RUN_START(bss_run), RUN_END(bss_end), SIZE(bss_size), RUN_END(__STACK_TOP) + +} diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_main.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_main.c new file mode 100644 index 0000000000000000000000000000000000000000..2724765980c712ef2242b4e8571bba2f51a2038a --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_main.c @@ -0,0 +1,989 @@ +//***************************************************************************** +// +// bl_main.c - The file holds the main control loop of the boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_gpio.h" +#include "inc/hw_flash.h" +#include "inc/hw_i2c.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "inc/hw_ssi.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "inc/hw_uart.h" +#include "bl_config.h" +#include "boot_loader/bl_commands.h" +#include "boot_loader/bl_decrypt.h" +#include "boot_loader/bl_flash.h" +#include "boot_loader/bl_hooks.h" +#include "boot_loader/bl_i2c.h" +#include "boot_loader/bl_packet.h" +#include "boot_loader/bl_ssi.h" +#include "boot_loader/bl_uart.h" +#ifdef CHECK_CRC +#include "boot_loader/bl_crc32.h" +#endif + +//***************************************************************************** +// +// Make sure that the application start address falls on a flash page boundary +// +//***************************************************************************** +#if (APP_START_ADDRESS & (FLASH_PAGE_SIZE - 1)) +#error ERROR: APP_START_ADDRESS must be a multiple of FLASH_PAGE_SIZE bytes! +#endif + +//***************************************************************************** +// +// Make sure that the flash reserved space is a multiple of flash pages. +// +//***************************************************************************** +#if (FLASH_RSVD_SPACE & (FLASH_PAGE_SIZE - 1)) +#error ERROR: FLASH_RSVD_SPACE must be a multiple of FLASH_PAGE_SIZE bytes! +#endif + +//***************************************************************************** +// +//! \addtogroup bl_main_api +//! @{ +// +//***************************************************************************** +#if defined(I2C_ENABLE_UPDATE) || defined(SSI_ENABLE_UPDATE) || \ + defined(UART_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for calling the +// application. +// +//***************************************************************************** +extern void CallApplication(uint32_t ui32Base); + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for a predictable length +// delay. +// +//***************************************************************************** +extern void Delay(uint32_t ui32Count); + +//***************************************************************************** +// +// Holds the current status of the last command that was issued to the boot +// loader. +// +//***************************************************************************** +uint8_t g_ui8Status; + +//***************************************************************************** +// +// This holds the current remaining size in bytes to be downloaded. +// +//***************************************************************************** +uint32_t g_ui32TransferSize; + +//***************************************************************************** +// +// This holds the total size of the firmware image being downloaded (if the +// protocol in use provides this). +// +//***************************************************************************** +#if (defined BL_PROGRESS_FN_HOOK) || (defined CHECK_CRC) +uint32_t g_ui32ImageSize; +#endif + +//***************************************************************************** +// +// This holds the current address that is being written to during a download +// command. +// +//***************************************************************************** +uint32_t g_ui32TransferAddress; +#ifdef CHECK_CRC +uint32_t g_ui32ImageAddress; +#endif + +//***************************************************************************** +// +// This is the data buffer used during transfers to the boot loader. +// +//***************************************************************************** +uint32_t g_pui32DataBuffer[BUFFER_SIZE]; + +//***************************************************************************** +// +// This is an specially aligned buffer pointer to g_pui32DataBuffer to make +// copying to the buffer simpler. It must be offset to end on an address that +// ends with 3. +// +//***************************************************************************** +uint8_t *g_pui8DataBuffer; + +//***************************************************************************** +// +// Converts a word from big endian to little endian. This macro uses compiler- +// specific constructs to perform an inline insertion of the "rev" instruction, +// which performs the byte swap directly. +// +//***************************************************************************** +#if defined(ewarm) +#include +#define SwapWord(x) __REV(x) +#endif +#if defined(codered) || defined(gcc) || defined(sourcerygxx) +#define SwapWord(x) __extension__ \ + ({ \ + register uint32_t __ret, __inp = x; \ + __asm__("rev %0, %1" : "=r" (__ret) : "r" (__inp)); \ + __ret; \ + }) +#endif +#if defined(rvmdk) || defined(__ARMCC_VERSION) +#define SwapWord(x) __rev(x) +#endif +#if defined(ccs) +uint32_t +SwapWord(uint32_t x) +{ + __asm(" rev r0, r0\n" + " bx lr\n"); // need this to make sure r0 is returned + return(x + 1); // return makes compiler happy - ignored +} +#endif + +//***************************************************************************** +// +//! Configures the microcontroller. +//! +//! This function configures the peripherals and GPIOs of the microcontroller, +//! preparing it for use by the boot loader. The interface that has been +//! selected as the update port will be configured, and auto-baud will be +//! performed if required. +//! +//! \return None. +// +//***************************************************************************** +void +ConfigureDevice(void) +{ +#ifdef UART_ENABLE_UPDATE + uint32_t ui32ProcRatio; +#endif + +#ifdef CRYSTAL_FREQ + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. + // +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. Check for whether the Oscillator range + // has to be set and wait states need to be updated + // + if(CRYSTAL_FREQ >= 10000000) + { + HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG); + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + else + { + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + + // + // Wait for the Oscillator to Stabilize + // + Delay(524288); + + if(CRYSTAL_FREQ > 16000000) + { + HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_FWS_S) | + SYSCTL_MEMTIM0_EBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_EWS_S) | + SYSCTL_MEMTIM0_MB1); + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_MEMTIMU | + SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } + else + { + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } +#else + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS); + Delay(524288); + HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & ~(SYSCTL_RCC_OSCSRC_M)) | + SYSCTL_RCC_OSCSRC_MAIN); +#endif +#endif + +#ifdef I2C_ENABLE_UPDATE + // + // Enable the clocks to the I2C and GPIO modules. + // + HWREG(SYSCTL_RCGCGPIO) |= (I2C_SCLPIN_CLOCK_ENABLE | + I2C_SDAPIN_CLOCK_ENABLE); + HWREG(SYSCTL_RCGCI2C) |= I2C_CLOCK_ENABLE; + + // + // Configure the GPIO pins for hardware control, open drain with pull-up, + // and enable them. + // + HWREG(I2C_SCLPIN_BASE + GPIO_O_AFSEL) |= I2C_CLK; + HWREG(I2C_SCLPIN_BASE + GPIO_O_PCTL) |= I2C_CLK_PCTL; + HWREG(I2C_SCLPIN_BASE + GPIO_O_DEN) |= I2C_CLK; + HWREG(I2C_SCLPIN_BASE + GPIO_O_ODR) &= ~(I2C_CLK); + HWREG(I2C_SCLPIN_BASE + GPIO_O_PUR) |= I2C_CLK; + + HWREG(I2C_SDAPIN_BASE + GPIO_O_AFSEL) |= I2C_DATA; + HWREG(I2C_SDAPIN_BASE + GPIO_O_PCTL) |= I2C_DATA_PCTL; + HWREG(I2C_SDAPIN_BASE + GPIO_O_DEN) |= I2C_DATA; + HWREG(I2C_SDAPIN_BASE + GPIO_O_ODR) |= I2C_DATA; + HWREG(I2C_SDAPIN_BASE + GPIO_O_PUR) |= I2C_DATA; + + // + // Enable the I2C Slave Mode. + // + HWREG(I2Cx_BASE + I2C_O_MCR) = I2C_MCR_MFE | I2C_MCR_SFE; + + // + // Setup the I2C Slave Address. + // + HWREG(I2Cx_BASE + I2C_O_SOAR) = I2C_SLAVE_ADDR; + + // + // Enable the I2C Slave Device on the I2C bus. + // + HWREG(I2Cx_BASE + I2C_O_SCSR) = I2C_SCSR_DA; +#endif + +#ifdef SSI_ENABLE_UPDATE + // + // Enable the clocks to the SSI and GPIO modules. + // + HWREG(SYSCTL_RCGCGPIO) |= (SSI_CLKPIN_CLOCK_ENABLE | + SSI_FSSPIN_CLOCK_ENABLE | + SSI_MISOPIN_CLOCK_ENABLE | + SSI_MOSIPIN_CLOCK_ENABLE); + HWREG(SYSCTL_RCGCSSI) |= SSI_CLOCK_ENABLE; + + // + // Make the pin be peripheral controlled. + // + HWREG(SSI_CLKPIN_BASE + GPIO_O_AFSEL) |= SSI_CLK; + HWREG(SSI_CLKPIN_BASE + GPIO_O_PCTL) |= SSI_CLK_PCTL; + HWREG(SSI_CLKPIN_BASE + GPIO_O_DEN) |= SSI_CLK; + HWREG(SSI_CLKPIN_BASE + GPIO_O_ODR) &= ~(SSI_CLK); + + HWREG(SSI_FSSPIN_BASE + GPIO_O_AFSEL) |= SSI_CS; + HWREG(SSI_FSSPIN_BASE + GPIO_O_PCTL) |= SSI_CS_PCTL; + HWREG(SSI_FSSPIN_BASE + GPIO_O_DEN) |= SSI_CS; + HWREG(SSI_FSSPIN_BASE + GPIO_O_ODR) &= ~(SSI_CS); + + HWREG(SSI_MISOPIN_BASE + GPIO_O_AFSEL) |= SSI_TX; + HWREG(SSI_MISOPIN_BASE + GPIO_O_PCTL) |= SSI_TX_PCTL; + HWREG(SSI_MISOPIN_BASE + GPIO_O_DEN) |= SSI_TX; + HWREG(SSI_MISOPIN_BASE + GPIO_O_ODR) &= ~(SSI_TX); + + HWREG(SSI_MOSIPIN_BASE + GPIO_O_AFSEL) |= SSI_RX; + HWREG(SSI_MOSIPIN_BASE + GPIO_O_PCTL) |= SSI_RX_PCTL; + HWREG(SSI_MOSIPIN_BASE + GPIO_O_DEN) |= SSI_RX; + HWREG(SSI_MOSIPIN_BASE + GPIO_O_ODR) &= ~(SSI_RX); + + // + // Set the SSI protocol to Motorola with default clock high and data + // valid on the rising edge. + // + HWREG(SSIx_BASE + SSI_O_CR0) = (SSI_CR0_SPH | SSI_CR0_SPO | + (DATA_BITS_SSI - 1)); + + // + // Enable the SSI interface in slave mode. + // + HWREG(SSIx_BASE + SSI_O_CR1) = SSI_CR1_MS | SSI_CR1_SSE; +#endif + +#ifdef UART_ENABLE_UPDATE + // + // Enable the the clocks to the UART and GPIO modules. + // + HWREG(SYSCTL_RCGCGPIO) |= (UART_RXPIN_CLOCK_ENABLE | + UART_TXPIN_CLOCK_ENABLE); + HWREG(SYSCTL_RCGCUART) |= UART_CLOCK_ENABLE; + + // + // Keep attempting to sync until we are successful. + // +#ifdef UART_AUTOBAUD + while(UARTAutoBaud(&ui32ProcRatio) < 0) + { + } +#else + ui32ProcRatio = UART_BAUD_RATIO(UART_FIXED_BAUDRATE); +#endif + + // + // Make the pin be peripheral controlled. + // + HWREG(UART_RXPIN_BASE + GPIO_O_AFSEL) |= UART_RX; + HWREG(UART_RXPIN_BASE + GPIO_O_PCTL) |= UART_RX_PCTL; + HWREG(UART_RXPIN_BASE + GPIO_O_ODR) &= ~(UART_RX); + HWREG(UART_RXPIN_BASE + GPIO_O_DEN) |= UART_RX; + + HWREG(UART_TXPIN_BASE + GPIO_O_AFSEL) |= UART_TX; + HWREG(UART_TXPIN_BASE + GPIO_O_PCTL) |= UART_TX_PCTL; + HWREG(UART_TXPIN_BASE + GPIO_O_ODR) &= ~(UART_TX); + HWREG(UART_TXPIN_BASE + GPIO_O_DEN) |= UART_TX; + + // + // Set the baud rate. + // + HWREG(UARTx_BASE + UART_O_IBRD) = ui32ProcRatio >> 6; + HWREG(UARTx_BASE + UART_O_FBRD) = ui32ProcRatio & UART_FBRD_DIVFRAC_M; + + // + // Set data length, parity, and number of stop bits to 8-N-1. + // + HWREG(UARTx_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; + + // + // Enable RX, TX, and the UART. + // + HWREG(UARTx_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); + +#ifdef UART_AUTOBAUD + // + // Need to ack in the UART case to hold it up while we get things set up. + // + AckPacket(); +#endif +#endif +} + +//***************************************************************************** +// +//! This function performs the update on the selected port. +//! +//! This function is called directly by the boot loader or it is called as a +//! result of an update request from the application. +//! +//! \return Never returns. +// +//***************************************************************************** +void +Updater(void) +{ + uint32_t ui32Size, ui32Temp, ui32FlashSize; +#ifdef CHECK_CRC + uint32_t ui32Retcode; +#endif + + // + // This ensures proper alignment of the global buffer so that the one byte + // size parameter used by the packetized format is easily skipped for data + // transfers. + // + g_pui8DataBuffer = ((uint8_t *)g_pui32DataBuffer) + 3; + + // + // Insure that the COMMAND_SEND_DATA cannot be sent to erase the boot + // loader before the application is erased. + // + g_ui32TransferAddress = 0xffffffff; + + // + // Read any data from the serial port in use. + // + while(1) + { + // + // Receive a packet from the port in use. + // + ui32Size = sizeof(g_pui32DataBuffer) - 3; + if(ReceivePacket(g_pui8DataBuffer, &ui32Size) != 0) + { + continue; + } + + // + // The first byte of the data buffer has the command and determines + // the format of the rest of the bytes. + // + switch(g_pui8DataBuffer[0]) + { + // + // This was a simple ping command. + // + case COMMAND_PING: + { + // + // This command always sets the status to COMMAND_RET_SUCCESS. + // + g_ui8Status = COMMAND_RET_SUCCESS; + + // + // Just acknowledge that the command was received. + // + AckPacket(); + + // + // Go back and wait for a new command. + // + break; + } + + // + // This command indicates the start of a download sequence. + // + case COMMAND_DOWNLOAD: + { + // + // Until determined otherwise, the command status is success. + // + g_ui8Status = COMMAND_RET_SUCCESS; + + // + // A simple do/while(0) control loop to make error exits + // easier. + // + do + { + // + // See if a full packet was received. + // + if(ui32Size != 9) + { + // + // Indicate that an invalid command was received. + // + g_ui8Status = COMMAND_RET_INVALID_CMD; + + // + // This packet has been handled. + // + break; + } + + // + // Get the address and size from the command. + // + g_ui32TransferAddress = SwapWord(g_pui32DataBuffer[1]); + g_ui32TransferSize = SwapWord(g_pui32DataBuffer[2]); + + // + // Depending upon the build options set, keep a copy of + // the original size and start address because we will need + // these later. + // +#if (defined BL_PROGRESS_FN_HOOK) || (defined CHECK_CRC) + g_ui32ImageSize = g_ui32TransferSize; +#endif +#ifdef CHECK_CRC + g_ui32ImageAddress = g_ui32TransferAddress; +#endif + + // + // Check for a valid starting address and image size. + // + if(!BL_FLASH_AD_CHECK_FN_HOOK(g_ui32TransferAddress, + g_ui32TransferSize)) + { + // + // Set the code to an error to indicate that the last + // command failed. This informs the updater program + // that the download command failed. + // + g_ui8Status = COMMAND_RET_INVALID_ADR; + + // + // This packet has been handled. + // + break; + } + + + // + // Only erase the space that we need if we are not + // protecting the code, otherwise erase the entire flash. + // +#ifdef FLASH_CODE_PROTECTION + ui32FlashSize = BL_FLASH_SIZE_FN_HOOK(); +#ifdef FLASH_RSVD_SPACE + if((ui32FlashSize - FLASH_RSVD_SPACE) != + g_ui32TransferAddress) + { + ui32FlashSize -= FLASH_RSVD_SPACE; + } +#endif +#else + ui32FlashSize = g_ui32TransferAddress + g_ui32TransferSize; +#endif + + // + // Clear the flash access interrupt. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // Leave the boot loader present until we start getting an + // image. + // + for(ui32Temp = g_ui32TransferAddress; + ui32Temp < ui32FlashSize; ui32Temp += FLASH_PAGE_SIZE) + { + // + // Erase this block. + // + BL_FLASH_ERASE_FN_HOOK(ui32Temp); + } + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + g_ui8Status = COMMAND_RET_FLASH_FAIL; + } + } + while(0); + + // + // See if the command was successful. + // + if(g_ui8Status != COMMAND_RET_SUCCESS) + { + // + // Setting g_ui32TransferSize to zero makes + // COMMAND_SEND_DATA fail to accept any data. + // + g_ui32TransferSize = 0; + } + + // + // Acknowledge that this command was received correctly. This + // does not indicate success, just that the command was + // received. + // + AckPacket(); + + // + // If we have a start notification hook function, call it + // now if everything is OK. + // +#ifdef BL_START_FN_HOOK + if(g_ui32TransferSize) + { + BL_START_FN_HOOK(); + } +#endif + + // + // Go back and wait for a new command. + // + break; + } + + // + // This command indicates that control should be transferred to + // the specified address. + // + case COMMAND_RUN: + { + // + // Acknowledge that this command was received correctly. This + // does not indicate success, just that the command was + // received. + // + AckPacket(); + + // + // See if a full packet was received. + // + if(ui32Size != 5) + { + // + // Indicate that an invalid command was received. + // + g_ui8Status = COMMAND_RET_INVALID_CMD; + + // + // This packet has been handled. + // + break; + } + + // + // Get the address to which control should be transferred. + // + g_ui32TransferAddress = SwapWord(g_pui32DataBuffer[1]); + + // + // This determines the size of the flash available on the + // device in use. + // + ui32FlashSize = BL_FLASH_SIZE_FN_HOOK(); + + // + // Test if the transfer address is valid for this device. + // + if(g_ui32TransferAddress >= ui32FlashSize) + { + // + // Indicate that an invalid address was specified. + // + g_ui8Status = COMMAND_RET_INVALID_ADR; + + // + // This packet has been handled. + // + break; + } + + // + // Make sure that the ACK packet has been sent. + // + FlushData(); + + // + // Reset and disable the peripherals used by the boot loader. + // +#ifdef I2C_ENABLE_UPDATE + HWREG(SYSCTL_RCGCI2C) &= ~I2C_CLOCK_ENABLE; + HWREG(SYSCTL_SRI2C) = I2C_CLOCK_ENABLE; + HWREG(SYSCTL_SRI2C) = 0; +#endif +#ifdef UART_ENABLE_UPDATE + HWREG(SYSCTL_RCGCUART) &= ~UART_CLOCK_ENABLE; + HWREG(SYSCTL_SRUART) = UART_CLOCK_ENABLE; + HWREG(SYSCTL_SRUART) = 0; +#endif +#ifdef SSI_ENABLE_UPDATE + HWREG(SYSCTL_RCGCSSI) &= ~SSI_CLOCK_ENABLE; + HWREG(SYSCTL_SRSSI) = SSI_CLOCK_ENABLE; + HWREG(SYSCTL_SRSSI) = 0; +#endif + + // + // Branch to the specified address. This should never return. + // If it does, very bad things will likely happen since it is + // likely that the copy of the boot loader in SRAM will have + // been overwritten. + // + ((void (*)(void))g_ui32TransferAddress)(); + + // + // In case this ever does return and the boot loader is still + // intact, simply reset the device. + // + HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | + NVIC_APINT_SYSRESETREQ); + + // + // The microcontroller should have reset, so this should + // never be reached. Just in case, loop forever. + // + while(1) + { + } + } + + // + // This command just returns the status of the last command that + // was sent. + // + case COMMAND_GET_STATUS: + { + // + // Acknowledge that this command was received correctly. This + // does not indicate success, just that the command was + // received. + // + AckPacket(); + + // + // Return the status to the updater. + // + SendPacket(&g_ui8Status, 1); + + // + // Go back and wait for a new command. + // + break; + } + + // + // This command is sent to transfer data to the device following + // a download command. + // + case COMMAND_SEND_DATA: + { + // + // Until determined otherwise, the command status is success. + // + g_ui8Status = COMMAND_RET_SUCCESS; + + // + // If this is overwriting the boot loader then the application + // has already been erased so now erase the boot loader. + // + if(g_ui32TransferAddress == 0) + { + // + // Clear the flash access interrupt. + // + BL_FLASH_CL_ERR_FN_HOOK(); + + // + // Erase the boot loader. + // + for(ui32Temp = 0; ui32Temp < APP_START_ADDRESS; + ui32Temp += FLASH_PAGE_SIZE) + { + // + // Erase this block. + // + BL_FLASH_ERASE_FN_HOOK(ui32Temp); + } + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + // + // Setting g_ui32TransferSize to zero makes + // COMMAND_SEND_DATA fail to accept any more data. + // + g_ui32TransferSize = 0; + + // + // Indicate that the flash erase failed. + // + g_ui8Status = COMMAND_RET_FLASH_FAIL; + } + } + + // + // Take one byte off for the command. + // + ui32Size = ui32Size - 1; + + // + // Check if there are any more bytes to receive. + // + if(g_ui32TransferSize >= ui32Size) + { + // + // If we have been provided with a decryption hook function + // call it here. + // +#ifdef BL_DECRYPT_FN_HOOK + BL_DECRYPT_FN_HOOK(g_pui8DataBuffer + 1, ui32Size); +#endif + + // + // Write this block of data to the flash + // + BL_FLASH_PROGRAM_FN_HOOK(g_ui32TransferAddress, + (uint8_t *) &g_pui32DataBuffer[1], + ((ui32Size + 3) & ~3)); + + // + // Return an error if an access violation occurred. + // + if(BL_FLASH_ERROR_FN_HOOK()) + { + // + // Indicate that the flash programming failed. + // + g_ui8Status = COMMAND_RET_FLASH_FAIL; + } + else + { + // + // Now update the address to program. + // + g_ui32TransferSize -= ui32Size; + g_ui32TransferAddress += ui32Size; + + // + // If a progress hook function has been provided, call + // it here. + // +#ifdef BL_PROGRESS_FN_HOOK + BL_PROGRESS_FN_HOOK(g_ui32ImageSize - + g_ui32TransferSize, + g_ui32ImageSize); +#endif + +#ifdef CHECK_CRC + // + // If we've reached the end, check the CRC in the + // image to determine whether or not we report an error + // back to the host. + // + if(g_ui32TransferSize == 0) + { + InitCRC32Table(); + ui32Retcode = CheckImageCRC32( + (uint32_t *)g_ui32ImageAddress); + + // + // Was the CRC good? We consider the CRC good if + // the header is found and the embedded CRC matches + // the calculated value or, if ENFORCE_CRC is not + // defined, if the header exists but is unpopulated. + // +#ifdef ENFORCE_CRC + if(ui32Retcode == CHECK_CRC_OK) +#else + if((ui32Retcode == CHECK_CRC_OK) || + (ui32Retcode == CHECK_CRC_NO_LENGTH)) +#endif + { + // + // The calculated CRC agreed with the embedded + // value. + // + g_ui8Status = COMMAND_RET_SUCCESS; + } + else + { + // + // The calculated CRC didn't match the expected + // value or the image didn't contain an embedded + // CRC. + // + g_ui8Status = COMMAND_RET_CRC_FAIL; + } + } +#endif + } + } + else + { + // + // This indicates that too much data is being sent to the + // device. + // + g_ui8Status = COMMAND_RET_INVALID_ADR; + } + + // + // Acknowledge that this command was received correctly. This + // does not indicate success, just that the command was + // received. + // + AckPacket(); + + // + // If we have an end notification hook function, and we've + // reached the end, call it now. + // +#ifdef BL_END_FN_HOOK + if(g_ui32TransferSize == 0) + { + BL_END_FN_HOOK(); + } +#endif + + // + // Go back and wait for a new command. + // + break; + } + + // + // This command is used to reset the device. + // + case COMMAND_RESET: + { + // + // Send out a one-byte ACK to ensure the byte goes back to the + // host before we reset everything. + // + AckPacket(); + + // + // Make sure that the ACK packet has been sent. + // + FlushData(); + + // + // Perform a software reset request. This will cause the + // microcontroller to reset; no further code will be executed. + // + HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | + NVIC_APINT_SYSRESETREQ); + + // + // The microcontroller should have reset, so this should never + // be reached. Just in case, loop forever. + // + while(1) + { + } + } + + // + // Just acknowledge the command and set the error to indicate that + // a bad command was sent. + // + default: + { + // + // Acknowledge that this command was received correctly. This + // does not indicate success, just that the command was + // received. + // + AckPacket(); + + // + // Indicate that a bad comand was sent. + // + g_ui8Status = COMMAND_RET_UNKNOWN_CMD; + + // + // Go back and wait for a new command. + // + break; + } + } + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.c new file mode 100644 index 0000000000000000000000000000000000000000..bbcd9c2421c5c9c56c3e8c64f3b7083225e7323f --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.c @@ -0,0 +1,295 @@ +//***************************************************************************** +// +// bl_packet.c - Packet handler functions used by the boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "bl_config.h" +#include "boot_loader/bl_commands.h" +#include "boot_loader/bl_i2c.h" +#include "boot_loader/bl_packet.h" +#include "boot_loader/bl_ssi.h" +#include "boot_loader/bl_uart.h" + +//***************************************************************************** +// +//! \addtogroup bl_packet_api +//! @{ +// +//***************************************************************************** +#if defined(I2C_ENABLE_UPDATE) || defined(SSI_ENABLE_UPDATE) || \ + defined(UART_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +// The packet that is sent to acknowledge a received packet. +// +//***************************************************************************** +static const uint8_t g_pui8ACK[2] = { 0, COMMAND_ACK }; + +//***************************************************************************** +// +// The packet that is sent to not-acknowledge a received packet. +// +//***************************************************************************** +static const uint8_t g_pui8NAK[2] = { 0, COMMAND_NAK }; + +//***************************************************************************** +// +//! Calculates an 8-bit checksum +//! +//! \param pui8Data is a pointer to an array of 8-bit data of size ui32Size. +//! \param ui32Size is the size of the array that will run through the checksum +//! algorithm. +//! +//! This function simply calculates an 8-bit checksum on the data passed in. +//! +//! \return Returns the calculated checksum. +// +//***************************************************************************** +uint32_t +CheckSum(const uint8_t *pui8Data, uint32_t ui32Size) +{ + uint32_t ui32CheckSum; + + // + // Initialize the checksum to zero. + // + ui32CheckSum = 0; + + // + // Add up all the bytes, do not do anything for an overflow. + // + while(ui32Size--) + { + ui32CheckSum += *pui8Data++; + } + + // + // Return the caculated check sum. + // + return(ui32CheckSum & 0xff); +} + +//***************************************************************************** +// +//! Sends an Acknowledge packet. +//! +//! This function is called to acknowledge that a packet has been received by +//! the microcontroller. +//! +//! \return None. +// +//***************************************************************************** +void +AckPacket(void) +{ + // + // ACK/NAK packets are the only ones with no size. + // + SendData(g_pui8ACK, 2); +} + +//***************************************************************************** +// +//! Sends a no-acknowledge packet. +//! +//! This function is called when an invalid packet has been received by the +//! microcontroller, indicating that it should be retransmitted. +//! +//! \return None. +// +//***************************************************************************** +void +NakPacket(void) +{ + // + // ACK/NAK packets are the only ones with no size. + // + SendData(g_pui8NAK, 2); +} + +//***************************************************************************** +// +//! Receives a data packet. +//! +//! \param pui8Data is the location to store the data that is sent to the boot +//! loader. +//! \param pui32Size is the number of bytes returned in the pui8Data buffer +//! that was provided. +//! +//! This function receives a packet of data from specified transfer function. +//! +//! \return Returns zero to indicate success while any non-zero value indicates +//! a failure. +// +//***************************************************************************** +int +ReceivePacket(uint8_t *pui8Data, uint32_t *pui32Size) +{ + uint32_t ui32Size, ui32CheckSum; + + // + // Wait for non-zero data before getting the first byte that holds the + // size of the packet we are receiving. + // + ui32Size = 0; + while(ui32Size == 0) + { + ReceiveData((uint8_t *)&ui32Size, 1); + } + + // + // Subtract off the size and checksum bytes. + // + ui32Size -= 2; + + // + // Receive the checksum followed by the actual data. + // + ReceiveData((uint8_t *)&ui32CheckSum, 1); + + // + // If there is room in the buffer then receive the requested data. + // + if(*pui32Size >= ui32Size) + { + // + // Receive the actual data in the packet. + // + ReceiveData(pui8Data, ui32Size); + + // + // Send a no acknowledge if the checksum does not match, otherwise send + // an acknowledge to the packet later. + // + if(CheckSum(pui8Data, ui32Size) != (ui32CheckSum & 0xff)) + { + // + // Indicate tha the packet was not received correctly. + // + NakPacket(); + + // + // Packet was not received, there is no valid data in the buffer. + // + return(-1); + } + } + else + { + // + // If the caller allocated a buffer that was too small for the received + // data packet, receive it but don't fill the buffer. + // Then inform the caller that the packet was not received correctly. + // + while(ui32Size--) + { + ReceiveData(pui8Data, 1); + } + + // + // Packet was not received, there is no valid data in the buffer. + // + return(-1); + } + + // + // Make sure to return the number of bytes received. + // + *pui32Size = ui32Size; + + // + // Packet was received successfully. + // + return(0); +} + +//***************************************************************************** +// +//! Sends a data packet. +//! +//! \param pui8Data is the location of the data to be sent. +//! \param ui32Size is the number of bytes to send. +//! +//! This function sends the data provided in the \e pui8Data parameter in the +//! packet format used by the boot loader. The caller only needs to specify +//! the buffer with the data that needs to be transferred. This function +//! addresses all other packet formatting issues. +//! +//! \return Returns zero to indicate success while any non-zero value indicates +//! a failure. +// +//***************************************************************************** +int +SendPacket(uint8_t *pui8Data, uint32_t ui32Size) +{ + uint32_t ui32Temp; + + // + // Caculate the checksum to be sent out with the data. + // + ui32Temp = CheckSum(pui8Data, ui32Size); + + // + // Need to include the size and checksum bytes in the packet. + // + ui32Size += 2; + + // + // Send out the size followed by the data. + // + SendData((uint8_t *)&ui32Size, 1); + SendData((uint8_t *)&ui32Temp, 1); + SendData(pui8Data, ui32Size - 2); + + // + // Wait for a non zero byte. + // + ui32Temp = 0; + while(ui32Temp == 0) + { + ReceiveData((uint8_t *)&ui32Temp, 1); + } + + // + // Check if the byte was a valid ACK and return a negative value if it was + // not and aknowledge. + // + if(ui32Temp != COMMAND_ACK) + { + return(-1); + } + + // + // This packet was sent and received successfully. + // + return(0); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.h new file mode 100644 index 0000000000000000000000000000000000000000..ffba38f740caafd4597347fb3f152e2012de52a7 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_packet.h @@ -0,0 +1,37 @@ +//***************************************************************************** +// +// bl_packet.h - The global variables and definitions of the boot loader. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_PACKET_H__ +#define __BL_PACKET_H__ + +//***************************************************************************** +// +// Packet Handling APIs +// +//***************************************************************************** +extern int ReceivePacket(uint8_t *pui8Data, uint32_t *pui32Size); +extern int SendPacket(uint8_t *pui8Data, uint32_t ui32Size); +extern void AckPacket(void); + +#endif // __BL_PACKET_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.c new file mode 100644 index 0000000000000000000000000000000000000000..e163e061a1e86b248cab9d14ed88650ab8b63d78 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.c @@ -0,0 +1,161 @@ +//***************************************************************************** +// +// bl_ssi.c - Functions used to transfer data via the SSI port. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_ssi.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "bl_config.h" +#include "boot_loader/bl_ssi.h" + +//***************************************************************************** +// +//! \addtogroup bl_ssi_api +//! @{ +// +//***************************************************************************** +#if defined(SSI_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +//! Sends data via the SSI port in slave mode. +//! +//! \param pui8Data is the location of the data to send through the SSI port. +//! \param ui32Size is the number of bytes of data to send. +//! +//! This function sends data through the SSI port in slave mode. This function +//! will not return until all bytes are sent. +//! +//! \return None. +// +//***************************************************************************** +void +SSISend(const uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Send the requested number of bytes over the SSI port. + // + while(ui32Size--) + { + // + // Wait until there is space in the SSI FIFO. + // + while(!(HWREG(SSIx_BASE + SSI_O_SR) & SSI_SR_TNF)) + { + } + + // + // Write the next byte to the SSI port. + // + HWREG(SSIx_BASE + SSI_O_DR) = *pui8Data++; + } + + // + // Empty the receive FIFO. + // + while(HWREG(SSIx_BASE + SSI_O_SR) & SSI_SR_RNE) + { + HWREG(SSIx_BASE + SSI_O_DR); + } +} + +//***************************************************************************** +// +//! Waits until all data has been transmitted by the SSI port. +//! +//! This function waits until all data written to the SSI port has been read by +//! the master. +//! +//! \return None. +// +//***************************************************************************** +void +SSIFlush(void) +{ + // + // Wait until the transmit FIFO is empty. + // + while(!(HWREG(SSIx_BASE + SSI_O_SR) & SSI_SR_TFE)) + { + } + + // + // Wait until the interface is not busy. + // + while(HWREG(SSIx_BASE + SSI_O_SR) & SSI_SR_BSY) + { + } +} + +//***************************************************************************** +// +//! Receives data from the SSI port in slave mode. +//! +//! \param pui8Data is the location to store the data received from the SSI +//! port. +//! \param ui32Size is the number of bytes of data to receive. +//! +//! This function receives data from the SSI port in slave mode. The function +//! will not return until \e ui32Size number of bytes have been received. +//! +//! \return None. +// +//***************************************************************************** +void +SSIReceive(uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Ensure that we are sending out zeros so that we don't confuse the host. + // + HWREG(SSIx_BASE + SSI_O_DR) = 0; + + // + // Wait for the requested number of bytes. + // + while(ui32Size--) + { + // + // Wait until there is data in the FIFO. + // + while(!(HWREG(SSIx_BASE + SSI_O_SR) & SSI_SR_RNE)) + { + } + + // + // Read the next byte from the FIFO. + // + *pui8Data++ = HWREG(SSIx_BASE + SSI_O_DR); + HWREG(SSIx_BASE + SSI_O_DR) = 0; + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.h new file mode 100644 index 0000000000000000000000000000000000000000..551144b21d45a2a43870fa275723dc726ab11f4e --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_ssi.h @@ -0,0 +1,213 @@ +//***************************************************************************** +// +// bl_ssi.h - Definitions for the SSI transport functions. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_SSI_H__ +#define __BL_SSI_H__ + +//***************************************************************************** +// +// This section maps the defines to default for SSI Boot Loader for legacy +// projects +// +//***************************************************************************** +#ifndef SSI_CLOCK_ENABLE +#define SSI_CLOCK_ENABLE SYSCTL_RCGCSSI_R0 +#endif + +#ifndef SSIx_BASE +#define SSIx_BASE SSI0_BASE +#endif + +#ifndef SSI_CLKPIN_CLOCK_ENABLE +#define SSI_CLKPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef SSI_CLKPIN_BASE +#define SSI_CLKPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef SSI_CLKPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_CLKPIN_PCTL 0xF +#else +#define SSI_CLKPIN_PCTL 0x2 +#endif +#endif + +#ifndef SSI_CLKPIN_POS +#define SSI_CLKPIN_POS 2 +#endif + +#ifndef SSI_FSSPIN_CLOCK_ENABLE +#define SSI_FSSPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef SSI_FSSPIN_BASE +#define SSI_FSSPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef SSI_FSSPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_FSSPIN_PCTL 0xF +#else +#define SSI_FSSPIN_PCTL 0x2 +#endif +#endif + +#ifndef SSI_FSSPIN_POS +#define SSI_FSSPIN_POS 3 +#endif + +#ifndef SSI_MISOPIN_CLOCK_ENABLE +#define SSI_MISOPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef SSI_MISOPIN_BASE +#define SSI_MISOPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef SSI_MISOPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_MISOPIN_PCTL 0xF +#else +#define SSI_MISOPIN_PCTL 0x2 +#endif +#endif + +#ifndef SSI_MISOPIN_POS +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_MISOPIN_POS 4 +#else +#define SSI_MISOPIN_POS 5 +#endif +#endif + +#ifndef SSI_MOSIPIN_CLOCK_ENABLE +#define SSI_MOSIPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef SSI_MOSIPIN_BASE +#define SSI_MOSIPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef SSI_MOSIPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_MOSIPIN_PCTL 0xF +#else +#define SSI_MOSIPIN_PCTL 0x2 +#endif +#endif + +#ifndef SSI_MOSIPIN_POS +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define SSI_MOSIPIN_POS 5 +#else +#define SSI_MOSIPIN_POS 4 +#endif +#endif + +//***************************************************************************** +// +// This is the number of bits per transfer for SSI. This is a constant and +// cannot be changed without corresponding code changes. +// +//***************************************************************************** +#define DATA_BITS_SSI 8 + +//***************************************************************************** +// +// This defines the SSI chip select pin that is being used by the boot loader. +// +//***************************************************************************** +#define SSI_CS (1 << SSI_FSSPIN_POS) +#define SSI_CS_PCTL (SSI_FSSPIN_PCTL << (4 * SSI_FSSPIN_POS)) + +//***************************************************************************** +// +// This defines the SSI clock pin that is being used by the boot loader. +// +//***************************************************************************** +#define SSI_CLK (1 << SSI_CLKPIN_POS) +#define SSI_CLK_PCTL (SSI_CLKPIN_PCTL << (4 * SSI_CLKPIN_POS)) + + +//***************************************************************************** +// +// This defines the SSI transmit pin that is being used by the boot loader. +// +//***************************************************************************** +#define SSI_TX (1 << SSI_MOSIPIN_POS) +#define SSI_TX_PCTL (SSI_MOSIPIN_PCTL << 4 * SSI_MOSIPIN_POS) + +//***************************************************************************** +// +// This defines the SSI receive pin that is being used by the boot loader. +// +//***************************************************************************** +#define SSI_RX (1 << SSI_MISOPIN_POS) +#define SSI_RX_PCTL (SSI_MISOPIN_PCTL << (4 * SSI_MISOPIN_POS)) + +//***************************************************************************** +// +// This defines the combination of pins used to implement the SSI port used by +// the boot loader. +// +//***************************************************************************** +#define SSI_PINS (SSI_CLK | SSI_TX | SSI_RX | SSI_CS) +#define SSI_PINS_PCTL (SSI_CLK_PCTL | SSI_TX_PCTL | SSI_RX_PCTL | \ + SSI_CS_PCTL) + +//***************************************************************************** +// +// SSI Transport APIs +// +//***************************************************************************** +extern void SSISend(const uint8_t *pui8Data, uint32_t ui32Size); +extern void SSIReceive(uint8_t *pui8Data, uint32_t ui32Size); +extern void SSIFlush(void); + +//***************************************************************************** +// +// Define the transport functions if the SSI port is being used. +// +//***************************************************************************** +#ifdef SSI_ENABLE_UPDATE +#define SendData SSISend +#define FlushData SSIFlush +#define ReceiveData SSIReceive +#endif + +#endif // __BL_SSI_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ccs.s b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ccs.s new file mode 100644 index 0000000000000000000000000000000000000000..2a965d682d8343933bb7b8b528f8530159abf51d --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ccs.s @@ -0,0 +1,660 @@ +;;***************************************************************************** +;; +;; bl_startup_ccs.s - Boot loader startup code for Code Composer Studio +;; +;; Copyright (c) 2009-2017 Texas Instruments Incorporated. All rights reserved. +;; Software License Agreement +;; +;; Texas Instruments (TI) is supplying this software for use solely and +;; exclusively on TI's microcontroller products. The software is owned by +;; TI and/or its suppliers, and is protected under applicable copyright +;; laws. You may not combine this software with "viral" open-source +;; software in order to form a larger program. +;; +;; THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +;; NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +;; NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +;; A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +;; CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +;; DAMAGES, FOR ANY REASON WHATSOEVER. +;; +;; This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +;; +;;***************************************************************************** + +;;***************************************************************************** +;; +;; Include the boot loader configuration options. +;; +;;***************************************************************************** + .cdecls C, NOLIST, WARN + %{ + #include "inc/hw_nvic.h" + #include "inc/hw_sysctl.h" + #include "bl_config.h" + %} + +;;***************************************************************************** +;; +;; Export symbols from this file that are used elsewhere +;; +;;***************************************************************************** + .global ResetISR, Delay, Vectors + +;;***************************************************************************** +;; +;; Create the stack and put it in a section +;; +;;***************************************************************************** + .global __stack +__stack:.usect ".stack", STACK_SIZE * 4, 8 + +;;***************************************************************************** +;; +;; Put the assembler into the correct configuration. +;; +;;***************************************************************************** + .thumb + +;;***************************************************************************** +;; +;; This portion of the file goes into interrupt vectors section +;; +;;***************************************************************************** + .sect ".intvecs" + +;;***************************************************************************** +;; +;; The minimal vector table for a Cortex-M3 processor. +;; +;;***************************************************************************** +Vectors: + .ref __STACK_TOP + .word __STACK_TOP ;; Offset 00: Initial stack pointer + .word ResetISR - 0x20000000 ;; Offset 04: Reset handler + .word NmiSR - 0x20000000 ;; Offset 08: NMI handler + .word FaultISR - 0x20000000 ;; Offset 0C: Hard fault handler + .word IntDefaultHandler ;; Offset 10: MPU fault handler + .word IntDefaultHandler ;; Offset 14: Bus fault handler + .word IntDefaultHandler ;; Offset 18: Usage fault handler + .word 0 ;; Offset 1C: Reserved + .word 0 ;; Offset 20: Reserved + .word 0 ;; Offset 24: Reserved + .word 0 ;; Offset 28: Reserved + .word UpdateHandler - 0x20000000 ;; Offset 2C: SVCall handler + .word IntDefaultHandler ;; Offset 30: Debug monitor handler + .word 0 ;; Offset 34: Reserved + .word IntDefaultHandler ;; Offset 38: PendSV handler + .if $$defined(ENET_ENABLE_UPDATE) + .ref SysTickIntHandler + .word SysTickIntHandler ;; Offset 3C: SysTick handler + .else + .word IntDefaultHandler ;; Offset 3C: SysTick handler + .endif + .if $$defined(UART_ENABLE_UPDATE) & $$defined(UART_AUTOBAUD) + .ref GPIOIntHandler + .word GPIOIntHandler ;; Offset 40: GPIO port A handler + .else + .word IntDefaultHandler ;; Offset 40: GPIO port A handler + .endif + .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler ;; Offset 44: GPIO Port B + .word IntDefaultHandler ;; Offset 48: GPIO Port C + .word IntDefaultHandler ;; Offset 4C: GPIO Port D + .word IntDefaultHandler ;; Offset 50: GPIO Port E + .word IntDefaultHandler ;; Offset 54: UART0 Rx and Tx + .word IntDefaultHandler ;; Offset 58: UART1 Rx and Tx + .word IntDefaultHandler ;; Offset 5C: SSI0 Rx and Tx + .word IntDefaultHandler ;; Offset 60: I2C0 Master and Slave + .word IntDefaultHandler ;; Offset 64: PWM Fault + .word IntDefaultHandler ;; Offset 68: PWM Generator 0 + .word IntDefaultHandler ;; Offset 6C: PWM Generator 1 + .word IntDefaultHandler ;; Offset 70: PWM Generator 2 + .word IntDefaultHandler ;; Offset 74: Quadrature Encoder 0 + .word IntDefaultHandler ;; Offset 78: ADC Sequence 0 + .word IntDefaultHandler ;; Offset 7C: ADC Sequence 1 + .word IntDefaultHandler ;; Offset 80: ADC Sequence 2 + .word IntDefaultHandler ;; Offset 84: ADC Sequence 3 + .word IntDefaultHandler ;; Offset 88: Watchdog timer + .word IntDefaultHandler ;; Offset 8C: Timer 0 subtimer A + .word IntDefaultHandler ;; Offset 90: Timer 0 subtimer B + .word IntDefaultHandler ;; Offset 94: Timer 1 subtimer A + .word IntDefaultHandler ;; Offset 98: Timer 1 subtimer B + .word IntDefaultHandler ;; Offset 9C: Timer 2 subtimer A + .word IntDefaultHandler ;; Offset A0: Timer 2 subtimer B + .word IntDefaultHandler ;; Offset A4: Analog Comparator 0 + .word IntDefaultHandler ;; Offset A8: Analog Comparator 1 + .word IntDefaultHandler ;; Offset AC: Analog Comparator 2 + .word IntDefaultHandler ;; Offset B0: System Control + .word IntDefaultHandler ;; Offset B4: FLASH Control + .endif + .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler ;; Offset B8: GPIO Port F + .word IntDefaultHandler ;; Offset BC: GPIO Port G + .word IntDefaultHandler ;; Offset C0: GPIO Port H + .word IntDefaultHandler ;; Offset C4: UART2 Rx and Tx + .word IntDefaultHandler ;; Offset C8: SSI1 Rx and Tx + .word IntDefaultHandler ;; Offset CC: Timer 3 subtimer A + .word IntDefaultHandler ;; Offset D0: Timer 3 subtimer B + .word IntDefaultHandler ;; Offset D4: I2C1 Master and Slave + .if ($$defined(TARGET_IS_TM4C129_RA0) | $$defined(TARGET_IS_TM4C129_RA1) | $$defined(TARGET_IS_TM4C129_RA2)) + .word IntDefaultHandler ;; Offset D8: CAN0 + .word IntDefaultHandler ;; Offset DC: CAN1 + .word IntDefaultHandler ;; Offset E0: Ethernet + .word IntDefaultHandler ;; Offset E4: Hibernation module + .if $$defined(USB_ENABLE_UPDATE) + .ref USB0DeviceIntHandler + .word USB0DeviceIntHandler ;; Offset E8: USB 0 Controller + .else + .word IntDefaultHandler ;; Offset E8: USB 0 Controller + .endif + .word IntDefaultHandler ;; Offset EC: PWM Generator 3 + .word IntDefaultHandler ;; Offset F0: uDMA 0 Software + .else + .word IntDefaultHandler ;; Offset D8: Quadrature Encoder 1 + .word IntDefaultHandler ;; Offset DC: CAN0 + .word IntDefaultHandler ;; Offset E0: CAN1 + .word IntDefaultHandler ;; Offset E4: CAN2 + .word IntDefaultHandler ;; Offset E8: Ethernet + .word IntDefaultHandler ;; Offset EC: Hibernation module + .if $$defined(USB_ENABLE_UPDATE) + .ref USB0DeviceIntHandler + .word USB0DeviceIntHandler ;; Offset F0: USB 0 Controller + .else + .word IntDefaultHandler ;; Offset F0: USB 0 Controller + .endif + .endif + .endif + +;;***************************************************************************** +;; +;; This portion of the file goes into the text section. +;; +;;***************************************************************************** + .text + +;;***************************************************************************** +;; +;; Initialize the processor by copying the boot loader from flash to SRAM, zero +;; filling the .bss section, and moving the vector table to the beginning of +;; SRAM. The return address is modified to point to the SRAM copy of the boot +;; loader instead of the flash copy, resulting in a branch to the copy now in +;; SRAM. +;; +;;***************************************************************************** + .ref bss_run +bss_start .word bss_run + .ref __STACK_TOP +bss_end .word __STACK_TOP + + .thumbfunc ProcessorInit +ProcessorInit: .asmfunc + ;; + ;; Copy the code image from flash to SRAM. + ;; + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + ldr r2, bss_start +copy_loop: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + ;; + ;; Zero fill the .bss section. + ;; + movs r0, #0x0000 + ldr r2, bss_end +zero_loop: + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + ;; + ;; Set the vector table pointer to the beginning of SRAM. + ;; + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + ;; + ;; Set the return address to the code just copied into SRAM. + ;; + orr lr, lr, #0x20000000 + + ;; + ;; Return to the caller. + ;; + bx lr + .endasmfunc + +;;***************************************************************************** +;; +;; The reset handler, which gets called when the processor starts. +;; +;;***************************************************************************** + .thumbfunc ResetISR +ResetISR: .asmfunc + ;; + ;; Enable the floating-point unit. This must be done here in case any + ;; later C functions use floating point. Note that some toolchains will + ;; use the FPU registers for general workspace even if no explicit floating + ;; point data types are in use. + ;; + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, r1, #0x00F00000 + str r1, [r0] + + ;; + ;; Initialize the processor. + ;; + bl ProcessorInit + + ;; + ;; Call the user-supplied low level hardware initialization function + ;; if provided. + ;; + .if $$defined(BL_HW_INIT_FN_HOOK) + .ref BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK + .endif + + ;; + ;; See if an update should be performed. + ;; + .ref CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + ;; + ;; Configure the microcontroller. + ;; + .thumbfunc EnterBootLoader +EnterBootLoader: + .if $$defined(ENET_ENABLE_UPDATE) + .ref ConfigureEnet + bl ConfigureEnet + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref ConfigureCAN + bl ConfigureCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref ConfigureUSB + bl ConfigureUSB + .else + .ref ConfigureDevice + bl ConfigureDevice + .endif + + ;; + ;; Call the user-supplied initialization function if provided. + ;; + .if $$defined(BL_INIT_FN_HOOK) + .ref BL_INIT_FN_HOOK + bl BL_INIT_FN_HOOK + .endif + + ;; + ;; Branch to the update handler. + ;; + .if $$defined(ENET_ENABLE_UPDATE) + .ref UpdateBOOTP + b UpdateBOOTP + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref UpdaterCAN + b UpdaterCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref UpdaterUSB + b UpdaterUSB + .else + .ref Updater + b Updater + .endif + .endasmfunc + + ;; + ;; This is a second symbol to allow starting the application from the boot + ;; loader the linker may not like the perceived jump. + ;; + .global StartApplication + .thumbfunc StartApplication +StartApplication: + ;; + ;; Call the application via the reset handler in its vector table. Load + ;; the address of the application vector table. + ;; + .thumbfunc CallApplication +CallApplication: .asmfunc + ;; + ;; Copy the application's vector table to the target address if necessary. + ;; Note that incorrect boot loader configuration could cause this to + ;; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ;; of SRAM) is safe since this will use the same memory that the boot loader + ;; already uses for its vector table. Great care will have to be taken if + ;; other addresses are to be used. + ;; + .if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) + .if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) + .endif + movw r1, #(APP_START_ADDRESS & 0xffff) + .if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) + .endif + + ;; + ;; Calculate the end address of the vector table assuming that it has the + ;; maximum possible number of vectors. We don't know how many the app has + ;; populated so this is the safest approach though it may copy some non + ;; vector data if the app table is smaller than the maximum. + ;; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop + .endif + + ;; + ;; Set the application's vector table start address. Typically this is the + ;; application start address but in some cases an application may relocate + ;; this so we can't assume that these two addresses are equal. + ;; + movw r0, #(VTABLE_START_ADDRESS & 0xffff) + .if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) + .endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ;; + ;; Load the stack pointer from the application's vector table. + ;; + .if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) + .if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) + .endif + .endif + ldr sp, [r0] + + ;; + ;; Load the initial PC from the application's vector table and branch to + ;; the application's entry point. + ;; + ldr r0, [r0, #4] + bx r0 + .endasmfunc + +;;***************************************************************************** +;; +;; The update handler, which gets called when the application would like to +;; start an update. +;; +;;***************************************************************************** + .thumbfunc UpdateHandler +UpdateHandler: .asmfunc + ;; + ;; Initialize the processor. + ;; + bl ProcessorInit + + ;; + ;; Load the stack pointer from the vector table. + ;; + movs r0, #0x0000 + ldr sp, [r0] + + ;; + ;; Call the user-supplied low level hardware initialization function + ;; if provided. + ;; + .if $$defined(BL_HW_INIT_FN_HOOK) + bl BL_HW_INIT_FN_HOOK + .endif + + ;; + ;; Call the user-supplied re-initialization function if provided. + ;; + .if $$defined(BL_REINIT_FN_HOOK) + .ref BL_REINIT_FN_HOOK + bl BL_REINIT_FN_HOOK + .endif + + ;; + ;; Branch to the update handler. + ;; + .if $$defined(ENET_ENABLE_UPDATE) + b UpdateBOOTP + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref AppUpdaterCAN + b AppUpdaterCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref AppUpdaterUSB + b AppUpdaterUSB + .else + b Updater + .endif + .endasmfunc + +;;***************************************************************************** +;; +;; The NMI handler. +;; +;;***************************************************************************** + .thumbfunc NmiSR +NmiSR: .asmfunc + .if $$defined(ENABLE_MOSCFAIL_HANDLER) + ;; + ;; Grab the fault frame from the stack (the stack will be cleared by the + ;; processor initialization that follows). + ;; + ldm sp, {r4-r11} + mov r12, lr + + ;; + ;; Initialize the processor. + ;; + bl ProcessorInit + + ;; + ;; Restore the stack frame. + ;; + mov lr, r12 + stm sp, {r4-r11} + + ;; + ;; Save the link register. + ;; + mov r9, lr + + ;; + ;; Call the user-supplied low level hardware initialization function + ;; if provided. + ;; + .if $$defined(BL_HW_INIT_FN_HOOK) + bl BL_HW_INIT_FN_HOOK + .endif + + ;; + ;; See if an update should be performed. + ;; + bl CheckForceUpdate + cbz r0, EnterApplication + + ;; + ;; Clear the MOSCFAIL bit in RESC. + ;; + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + ;; + ;; Fix up the PC on the stack so that the boot pin check is bypassed + ;; (since it has already been performed). + ;; + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + ;; + ;; Return from the NMI handler. This will then start execution of the + ;; boot loader. + ;; + bx r9 + + ;; + ;; Restore the link register. + ;; +EnterApplication: + mov lr, r9 + + ;; + ;; Copy the application's vector table to the target address if necessary. + ;; Note that incorrect boot loader configuration could cause this to + ;; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ;; of SRAM) is safe since this will use the same memory that the boot loader + ;; already uses for its vector table. Great care will have to be taken if + ;; other addresses are to be used. + ;; + .if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) + .if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) + .endif + movw r1, #(APP_START_ADDRESS & 0xffff) + .if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) + .endif + + ;; + ;; Calculate the end address of the vector table assuming that it has the + ;; maximum possible number of vectors. We don't know how many the app has + ;; populated so this is the safest approach though it may copy some non + ;; vector data if the app table is smaller than the maximum. + ;; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 + .endif + + ;; + ;; Set the application's vector table start address. Typically this is the + ;; application start address but in some cases an application may relocate + ;; this so we can't assume that these two addresses are equal. + ;; + movw r0, #(VTABLE_START_ADDRESS & 0xffff) + .if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) + .endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ;; + ;; Remove the NMI stack frame from the boot loader's stack. + ;; + ldmia sp, {r4-r11} + + ;; + ;; Get the application's stack pointer. + ;; + .if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) + .if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) + .endif + .endif + ldr sp, [r0, #0x00] + + ;; + ;; Fix up the NMI stack frame's return address to be the reset handler of + ;; the application. + ;; + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + ;; + ;; Store the NMI stack frame onto the application's stack. + ;; + stmdb sp!, {r4-r11} + + ;; + ;; Branch to the application's NMI handler. + ;; + ldr r0, [r0, #0x08] + bx r0 + .else + ;; + ;; Loop forever since there is nothing that we can do about a NMI. + ;; + b NmiSR + .endif + .endasmfunc + +;;***************************************************************************** +;; +;; The hard fault handler. +;; +;;***************************************************************************** + .thumbfunc FaultISR +FaultISR: .asmfunc + ;; + ;; Loop forever since there is nothing that we can do about a hard fault. + ;; + b FaultISR + .endasmfunc + +;;***************************************************************************** +;; +;; The default interrupt handler. +;; +;;***************************************************************************** + .thumbfunc IntDefaultHandler +IntDefaultHandler: .asmfunc + ;; + ;; Loop forever since there is nothing that we can do about an unexpected + ;; interrupt. + ;; + b IntDefaultHandler + .endasmfunc + +;;***************************************************************************** +;; +;; Provides a small delay. The loop below takes 3 cycles/loop. +;; +;;***************************************************************************** +; .globl Delay + .thumbfunc Delay +Delay: .asmfunc + subs r0, #1 + bne Delay + bx lr + .endasmfunc + + .thumbfunc _c_int00 + .global _c_int00 +_c_int00: .asmfunc + b ResetISR + +;;***************************************************************************** +;; +;; This is the end of the file. +;; +;;***************************************************************************** + .end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ewarm.S b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ewarm.S new file mode 100644 index 0000000000000000000000000000000000000000..65c4cdcbf2f00e5018e90c098841a0c4bcd98d02 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_ewarm.S @@ -0,0 +1,628 @@ +//***************************************************************************** +// +// bl_startup_ewarm.S - Startup code for EWARM. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +//***************************************************************************** +// +// Include the assember definitions used to make this code compiler +// independent. +// +//***************************************************************************** +#include "inc/hw_nvic.h" +#include "inc/hw_sysctl.h" +#include "bl_config.h" + +//***************************************************************************** +// +// The stack gets placed into the zero-init section. +// +//***************************************************************************** + rseg .bss:DATA(2) + +//***************************************************************************** +// +// Allocate storage for the stack. +// +//***************************************************************************** + export g_pulStack +g_pulStack ds8 STACK_SIZE * 4 + +//***************************************************************************** +// +// This portion of the file goes into the vector section. +// +//***************************************************************************** + rseg INTVEC:CONST(2) + +//***************************************************************************** +// +// The minimal vector table for a Cortex-M3 processor. +// +//***************************************************************************** + export __vector_table +__vector_table + dcd g_pulStack + (STACK_SIZE * 4) // Offset 00: Initial stack pointer + dcd ResetISR - 0x20000000 // Offset 04: Reset handler + dcd NmiSR - 0x20000000 // Offset 08: NMI handler + dcd FaultISR - 0x20000000 // Offset 0C: Hard fault handler + dcd IntDefaultHandler // Offset 10: MPU fault handler + dcd IntDefaultHandler // Offset 14: Bus fault handler + dcd IntDefaultHandler // Offset 18: Usage fault handler + dcd 0 // Offset 1C: Reserved + dcd 0 // Offset 20: Reserved + dcd 0 // Offset 24: Reserved + dcd 0 // Offset 28: Reserved + dcd UpdateHandler - 0x20000000 // Offset 2C: SVCall handler + dcd IntDefaultHandler // Offset 30: Debug monitor handler + dcd 0 // Offset 34: Reserved + dcd IntDefaultHandler // Offset 38: PendSV handler +#if defined(ENET_ENABLE_UPDATE) + import SysTickIntHandler + dcd SysTickIntHandler // Offset 3C: SysTick handler +#else + dcd IntDefaultHandler // Offset 3C: SysTick handler +#endif +#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) + import GPIOIntHandler + dcd GPIOIntHandler // Offset 40: GPIO port A handler +#else + dcd IntDefaultHandler // Offset 40: GPIO port A handler +#endif +#if (defined(USB_ENABLE_UPDATE) || \ + (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + dcd IntDefaultHandler // Offset 44: GPIO Port B + dcd IntDefaultHandler // Offset 48: GPIO Port C + dcd IntDefaultHandler // Offset 4C: GPIO Port D + dcd IntDefaultHandler // Offset 50: GPIO Port E + dcd IntDefaultHandler // Offset 54: UART0 Rx and Tx + dcd IntDefaultHandler // Offset 58: UART1 Rx and Tx + dcd IntDefaultHandler // Offset 5C: SSI0 Rx and Tx + dcd IntDefaultHandler // Offset 60: I2C0 Master and Slave + dcd IntDefaultHandler // Offset 64: PWM Fault + dcd IntDefaultHandler // Offset 68: PWM Generator 0 + dcd IntDefaultHandler // Offset 6C: PWM Generator 1 + dcd IntDefaultHandler // Offset 70: PWM Generator 2 + dcd IntDefaultHandler // Offset 74: Quadrature Encoder 0 + dcd IntDefaultHandler // Offset 78: ADC Sequence 0 + dcd IntDefaultHandler // Offset 7C: ADC Sequence 1 + dcd IntDefaultHandler // Offset 80: ADC Sequence 2 + dcd IntDefaultHandler // Offset 84: ADC Sequence 3 + dcd IntDefaultHandler // Offset 88: Watchdog timer + dcd IntDefaultHandler // Offset 8C: Timer 0 subtimer A + dcd IntDefaultHandler // Offset 90: Timer 0 subtimer B + dcd IntDefaultHandler // Offset 94: Timer 1 subtimer A + dcd IntDefaultHandler // Offset 98: Timer 1 subtimer B + dcd IntDefaultHandler // Offset 9C: Timer 2 subtimer A + dcd IntDefaultHandler // Offset A0: Timer 2 subtimer B + dcd IntDefaultHandler // Offset A4: Analog Comparator 0 + dcd IntDefaultHandler // Offset A8: Analog Comparator 1 + dcd IntDefaultHandler // Offset AC: Analog Comparator 2 + dcd IntDefaultHandler // Offset B0: System Control + dcd IntDefaultHandler // Offset B4: FLASH Control +#endif +#if (defined(USB_ENABLE_UPDATE) || (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + dcd IntDefaultHandler // Offset B8: GPIO Port F + dcd IntDefaultHandler // Offset BC: GPIO Port G + dcd IntDefaultHandler // Offset C0: GPIO Port H + dcd IntDefaultHandler // Offset C4: UART2 Rx and Tx + dcd IntDefaultHandler // Offset C8: SSI1 Rx and Tx + dcd IntDefaultHandler // Offset CC: Timer 3 subtimer A + dcd IntDefaultHandler // Offset D0: Timer 3 subtimer B + dcd IntDefaultHandler // Offset D4: I2C1 Master and Slave +#if (defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2)) + dcd IntDefaultHandler // Offset D8: CAN0 + dcd IntDefaultHandler // Offset DC: CAN1 + dcd IntDefaultHandler // Offset E0: Ethernet + dcd IntDefaultHandler // Offset E4: Hibernation module +#if defined(USB_ENABLE_UPDATE) + import USB0DeviceIntHandler + dcd USB0DeviceIntHandler // Offset E8: USB 0 Controller +#else + dcd IntDefaultHandler // Offset E8: USB 0 Controller +#endif + dcd IntDefaultHandler // Offset EC: PWM Generator 3 + dcd IntDefaultHandler // Offset F0: uDMA 0 Software +#else + dcd IntDefaultHandler // Offset D8: Quadrature Encoder 1 + dcd IntDefaultHandler // Offset DC: CAN0 + dcd IntDefaultHandler // Offset E0: CAN1 + dcd IntDefaultHandler // Offset E4: CAN2 + dcd IntDefaultHandler // Offset E8: Ethernet + dcd IntDefaultHandler // Offset EC: Hibernation module +#if defined(USB_ENABLE_UPDATE) + import USB0DeviceIntHandler + dcd USB0DeviceIntHandler // Offset F0: USB 0 Controller +#else + dcd IntDefaultHandler // Offset F0: USB 0 Controller +#endif +#endif +#endif + +//***************************************************************************** +// +// This portion of the file goes into the text section. +// +//***************************************************************************** + rseg CODE:CODE(2) + thumb + +//***************************************************************************** +// +// Initialize the processor by copying the boot loader from flash to SRAM, zero +// filling the .bss section, and moving the vector table to the beginning of +// SRAM. The return address is modified to point to the SRAM copy of the boot +// loader instead of the flash copy, resulting in a branch to the copy now in +// SRAM. +// +//***************************************************************************** +ProcessorInit + // + // Copy the code image from flash to SRAM. + // + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + ldr r2, =SFB(.bss) +copy_loop + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + // + // Zero fill the .bss section. + // + movs r0, #0x0000 + ldr r2, =SFE(.bss) +zero_loop + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + // + // Set the vector table pointer to the beginning of SRAM. + // + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + // + // Set the return address to the code just copied into SRAM. + // + orr lr, lr, #0x20000000 + + // + // Return to the caller. + // + bx lr + +//***************************************************************************** +// +// The reset handler, which gets called when the processor starts. +// +//***************************************************************************** + export ResetISR +ResetISR + // + // Enable the floating-point unit. This must be done here in case any + // later C functions use floating point. Note that some toolchains will + // use the FPU registers for general workspace even if no explicit floating + // point data types are in use. + // + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, r1, #0x00F00000 + str r1, [r0] + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + import BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + import CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + // + // Configure the microcontroller. + // +EnterBootLoader +#ifdef ENET_ENABLE_UPDATE + import ConfigureEnet + bl ConfigureEnet +#elif defined(CAN_ENABLE_UPDATE) + import ConfigureCAN + bl ConfigureCAN +#elif defined(USB_ENABLE_UPDATE) + import ConfigureUSB + bl ConfigureUSB +#else + import ConfigureDevice + bl ConfigureDevice +#endif + + // + // Call the user-supplied initialization function if provided. + // +#ifdef BL_INIT_FN_HOOK + import BL_INIT_FN_HOOK + bl BL_INIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + import UpdateBOOTP + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + import UpdaterCAN + b UpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + import UpdaterUSB + b UpdaterUSB +#else + import Updater + b Updater +#endif + + // + // This is a second symbol to allow starting the application from the boot + // loader the linker may not like the perceived jump. + // + export StartApplication +StartApplication + // + // Call the application via the reset handler in its vector table. Load + // the address of the application's vector table first. + // +CallApplication + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Load the stack pointer from the application's vector table at the + // beginning of the image. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0] + + // + // Load the initial PC from the application's vector table and branch to + // the application's entry point. + // + ldr r0, [r0, #4] + bx r0 + +//***************************************************************************** +// +// The update handler, which gets called when the application would like to +// start an update. +// +//***************************************************************************** +UpdateHandler + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Load the stack pointer from the vector table. + // + movs r0, #0x0000 + ldr sp, [r0] + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // Call the user-supplied re-initialization function if provided. + // +#ifdef BL_REINIT_FN_HOOK + import BL_REINIT_FN_HOOK + bl BL_REINIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + import AppUpdaterCAN + b AppUpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + import AppUpdaterUSB + b AppUpdaterUSB +#else + b Updater +#endif + +//***************************************************************************** +// +// The NMI handler. +// +//***************************************************************************** +NmiSR +#ifdef ENABLE_MOSCFAIL_HANDLER + // + // Grab the fault frame from the stack (the stack will be cleared by the + // processor initialization that follows). + // + ldm sp, {r4-r11} + mov r12, lr + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Restore the stack frame. + // + mov lr, r12 + stm sp, {r4-r11} + + // + // Save the link register. + // + mov r9, lr + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + bl CheckForceUpdate + cbz r0, EnterApplication + + // + // Clear the MOSCFAIL bit in RESC. + // + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + // + // Fix up the PC on the stack so that the boot pin check is bypassed + // (since it has already been performed). + // + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + // + // Return from the NMI handler. This will then start execution of the + // boot loader. + // + bx r9 + + // + // Restore the link register. + // +EnterApplication: + mov lr, r9 + + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Remove the NMI stack frame from the boot loader's stack. + // + ldmia sp, {r4-r11} + + // + // Get the application's stack pointer. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0, #0x00] + + // + // Fix up the NMI stack frame's return address to be the reset handler of + // the application. + // + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + // + // Store the NMI stack frame onto the application's stack. + // + stmdb sp!, {r4-r11} + + // + // Branch to the application's NMI handler. + // + ldr r0, [r0, #0x08] + bx r0 +#else + // + // Loop forever since there is nothing that we can do about a NMI. + // + b . +#endif + +//***************************************************************************** +// +// The hard fault handler. +// +//***************************************************************************** +FaultISR + // + // Loop forever since there is nothing that we can do about a hard fault. + // + b . + +//***************************************************************************** +// +// The default interrupt handler. +// +//***************************************************************************** +IntDefaultHandler + // + // Loop forever since there is nothing that we can do about an unexpected + // interrupt. + // + b . + +//***************************************************************************** +// +// Provides a small delay. The loop below takes 3 cycles/loop. +// +//***************************************************************************** + export Delay +Delay + subs r0, #1 + bne Delay + bx lr + +//***************************************************************************** +// +// This is the end of the file. +// +//***************************************************************************** + end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_gcc.S b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..5e2eaf653d23fde61de25d94936e9fd6c5c782c8 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_gcc.S @@ -0,0 +1,646 @@ +//***************************************************************************** +// +// bl_startup_gcc.S - Startup code for GNU. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +//***************************************************************************** +// +// Include the assember definitions used to make this code compiler +// independent. +// +//***************************************************************************** +#include "inc/hw_nvic.h" +#include "inc/hw_sysctl.h" +#include "bl_config.h" + +//***************************************************************************** +// +// Put the assembler into the correct configuration. +// +//***************************************************************************** + .syntax unified + .thumb + +//***************************************************************************** +// +// The stack gets placed into the zero-init section. +// +//***************************************************************************** + .bss + +//***************************************************************************** +// +// Allocate storage for the stack. +// +//***************************************************************************** +g_pulStack: + .space STACK_SIZE * 4 + +//***************************************************************************** +// +// This portion of the file goes into the text section. +// +//***************************************************************************** + .section .isr_vector + +//***************************************************************************** +// +// The minimal vector table for a Cortex-M3 processor. +// +//***************************************************************************** +Vectors: + .word g_pulStack + (STACK_SIZE * 4) // Offset 00: Initial stack pointer + .word ResetISR - 0x20000000 // Offset 04: Reset handler + .word NmiSR - 0x20000000 // Offset 08: NMI handler + .word FaultISR - 0x20000000 // Offset 0C: Hard fault handler + .word IntDefaultHandler // Offset 10: MPU fault handler + .word IntDefaultHandler // Offset 14: Bus fault handler + .word IntDefaultHandler // Offset 18: Usage fault handler + .word 0 // Offset 1C: Reserved + .word 0 // Offset 20: Reserved + .word 0 // Offset 24: Reserved + .word 0 // Offset 28: Reserved + .word UpdateHandler - 0x20000000 // Offset 2C: SVCall handler + .word IntDefaultHandler // Offset 30: Debug monitor handler + .word 0 // Offset 34: Reserved + .word IntDefaultHandler // Offset 38: PendSV handler +#if defined(ENET_ENABLE_UPDATE) + .extern SysTickIntHandler + .word SysTickIntHandler // Offset 3C: SysTick handler +#else + .word IntDefaultHandler // Offset 3C: SysTick handler +#endif +#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) + .extern GPIOIntHandler + .word GPIOIntHandler // Offset 40: GPIO port A handler +#else + .word IntDefaultHandler // Offset 40: GPIO port A handler +#endif +#if (defined(USB_ENABLE_UPDATE) || \ + (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler // Offset 44: GPIO Port B + .word IntDefaultHandler // Offset 48: GPIO Port C + .word IntDefaultHandler // Offset 4C: GPIO Port D + .word IntDefaultHandler // Offset 50: GPIO Port E + .word IntDefaultHandler // Offset 54: UART0 Rx and Tx + .word IntDefaultHandler // Offset 58: UART1 Rx and Tx + .word IntDefaultHandler // Offset 5C: SSI0 Rx and Tx + .word IntDefaultHandler // Offset 60: I2C0 Master and Slave + .word IntDefaultHandler // Offset 64: PWM Fault + .word IntDefaultHandler // Offset 68: PWM Generator 0 + .word IntDefaultHandler // Offset 6C: PWM Generator 1 + .word IntDefaultHandler // Offset 70: PWM Generator 2 + .word IntDefaultHandler // Offset 74: Quadrature Encoder 0 + .word IntDefaultHandler // Offset 78: ADC Sequence 0 + .word IntDefaultHandler // Offset 7C: ADC Sequence 1 + .word IntDefaultHandler // Offset 80: ADC Sequence 2 + .word IntDefaultHandler // Offset 84: ADC Sequence 3 + .word IntDefaultHandler // Offset 88: Watchdog timer + .word IntDefaultHandler // Offset 8C: Timer 0 subtimer A + .word IntDefaultHandler // Offset 90: Timer 0 subtimer B + .word IntDefaultHandler // Offset 94: Timer 1 subtimer A + .word IntDefaultHandler // Offset 98: Timer 1 subtimer B + .word IntDefaultHandler // Offset 9C: Timer 2 subtimer A + .word IntDefaultHandler // Offset A0: Timer 2 subtimer B + .word IntDefaultHandler // Offset A4: Analog Comparator 0 + .word IntDefaultHandler // Offset A8: Analog Comparator 1 + .word IntDefaultHandler // Offset AC: Analog Comparator 2 + .word IntDefaultHandler // Offset B0: System Control + .word IntDefaultHandler // Offset B4: FLASH Control +#endif +#if (defined(USB_ENABLE_UPDATE) || (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler // Offset B8: GPIO Port F + .word IntDefaultHandler // Offset BC: GPIO Port G + .word IntDefaultHandler // Offset C0: GPIO Port H + .word IntDefaultHandler // Offset C4: UART2 Rx and Tx + .word IntDefaultHandler // Offset C8: SSI1 Rx and Tx + .word IntDefaultHandler // Offset CC: Timer 3 subtimer A + .word IntDefaultHandler // Offset D0: Timer 3 subtimer B + .word IntDefaultHandler // Offset D4: I2C1 Master and Slave +#if (defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2)) + .word IntDefaultHandler // Offset D8: CAN0 + .word IntDefaultHandler // Offset DC: CAN1 + .word IntDefaultHandler // Offset E0: Ethernet + .word IntDefaultHandler // Offset E4: Hibernation module +#if defined(USB_ENABLE_UPDATE) + .extern USB0DeviceIntHandler + .word USB0DeviceIntHandler // Offset E8: USB 0 Controller +#else + .word IntDefaultHandler // Offset E8: USB 0 Controller +#endif + .word IntDefaultHandler // Offset EC: PWM Generator 3 + .word IntDefaultHandler // Offset F0: uDMA 0 Software +#else + .word IntDefaultHandler // Offset D8: Quadrature Encoder 1 + .word IntDefaultHandler // Offset DC: CAN0 + .word IntDefaultHandler // Offset E0: CAN1 + .word IntDefaultHandler // Offset E4: CAN2 + .word IntDefaultHandler // Offset E8: Ethernet + .word IntDefaultHandler // Offset EC: Hibernation module +#if defined(USB_ENABLE_UPDATE) + .extern USB0DeviceIntHandler + .word USB0DeviceIntHandler // Offset F0: USB 0 Controller +#else + .word IntDefaultHandler // Offset F0: USB 0 Controller +#endif +#endif +#endif + +//***************************************************************************** +// +// This portion of the file goes into the text section. +// +//***************************************************************************** + .text + +//***************************************************************************** +// +// Initialize the processor by copying the boot loader from flash to SRAM, zero +// filling the .bss section, and moving the vector table to the beginning of +// SRAM. The return address is modified to point to the SRAM copy of the boot +// loader instead of the flash copy, resulting in a branch to the copy now in +// SRAM. +// +//***************************************************************************** + .thumb_func +ProcessorInit: + // + // Copy the code image from flash to SRAM. + // + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + .extern _bss + ldr r2, =_bss +copy_loop: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + // + // Zero fill the .bss section. + // + movs r0, #0x0000 + .extern _ebss + ldr r2, =_ebss +zero_loop: + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + // + // Set the vector table pointer to the beginning of SRAM. + // + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + // + // Set the return address to the code just copied into SRAM. + // + orr lr, lr, #0x20000000 + + // + // Return to the caller. + // + bx lr + +//***************************************************************************** +// +// The reset handler, which gets called when the processor starts. +// +//***************************************************************************** + .globl ResetISR + .thumb_func +ResetISR: + // + // Enable the floating-point unit. This must be done here in case any + // later C functions use floating point. Note that some toolchains will + // use the FPU registers for general workspace even if no explicit floating + // point data types are in use. + // + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, r1, #0x00F00000 + str r1, [r0] + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + .extern BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + .extern CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + // + // Configure the microcontroller. + // + .thumb_func +EnterBootLoader: +#ifdef ENET_ENABLE_UPDATE + .extern ConfigureEnet + bl ConfigureEnet +#elif defined(CAN_ENABLE_UPDATE) + .extern ConfigureCAN + bl ConfigureCAN +#elif defined(USB_ENABLE_UPDATE) + .extern ConfigureUSB + bl ConfigureUSB +#else + .extern ConfigureDevice + bl ConfigureDevice +#endif + + // + // Call the user-supplied initialization function if provided. + // +#ifdef BL_INIT_FN_HOOK + .extern BL_INIT_FN_HOOK + bl BL_INIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + .extern UpdateBOOTP + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + .extern UpdaterCAN + b UpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + .extern UpdaterUSB + b UpdaterUSB +#else + .extern Updater + b Updater +#endif + + // + // This is a second symbol to allow starting the application from the boot + // loader the linker may not like the perceived jump. + // + .globl StartApplication + .thumb_func +StartApplication: + // + // Call the application via the reset handler in its vector table. Load + // the address of the application vector table. + // + .thumb_func +CallApplication: + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Load the stack pointer from the application's vector table. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0] + + // + // Load the initial PC from the application's vector table and branch to + // the application's entry point. + // + ldr r0, [r0, #4] + bx r0 + +//***************************************************************************** +// +// The update handler, which gets called when the application would like to +// start an update. +// +//***************************************************************************** + .thumb_func +UpdateHandler: + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Load the stack pointer from the vector table. + // + movs r0, #0x0000 + ldr sp, [r0] + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // Call the user-supplied re-initialization function if provided. + // +#ifdef BL_REINIT_FN_HOOK + .extern BL_REINIT_FN_HOOK + bl BL_REINIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + .extern AppUpdaterCAN + b AppUpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + .extern AppUpdaterUSB + b AppUpdaterUSB +#else + b Updater +#endif + +//***************************************************************************** +// +// The NMI handler. +// +//***************************************************************************** + .thumb_func +NmiSR: +#ifdef ENABLE_MOSCFAIL_HANDLER + // + // Grab the fault frame from the stack (the stack will be cleared by the + // processor initialization that follows). + // + ldm sp, {r4-r11} + mov r12, lr + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Restore the stack frame. + // + mov lr, r12 + stm sp, {r4-r11} + + // + // Save the link register. + // + mov r9, lr + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + bl CheckForceUpdate + cbz r0, EnterApplication + + // + // Clear the MOSCFAIL bit in RESC. + // + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + // + // Fix up the PC on the stack so that the boot pin check is bypassed + // (since it has already been performed). + // + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + // + // Return from the NMI handler. This will then start execution of the + // boot loader. + // + bx r9 + + // + // Restore the link register. + // + .thumb_func +EnterApplication: + mov lr, r9 + + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Remove the NMI stack frame from the boot loader's stack. + // + ldmia sp, {r4-r11} + + // + // Get the application's stack pointer. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0, #0x00] + + // + // Fix up the NMI stack frame's return address to be the reset handler of + // the application. + // + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + // + // Store the NMI stack frame onto the application's stack. + // + stmdb sp!, {r4-r11} + + // + // Branch to the application's NMI handler. + // + ldr r0, [r0, #0x08] + bx r0 +#else + // + // Loop forever since there is nothing that we can do about a NMI. + // + b . +#endif + +//***************************************************************************** +// +// The hard fault handler. +// +//***************************************************************************** + .thumb_func +FaultISR: + // + // Loop forever since there is nothing that we can do about a hard fault. + // + b . + +//***************************************************************************** +// +// The default interrupt handler. +// +//***************************************************************************** + .thumb_func +IntDefaultHandler: + // + // Loop forever since there is nothing that we can do about an unexpected + // interrupt. + // + b . + +//***************************************************************************** +// +// Provides a small delay. The loop below takes 3 cycles/loop. +// +//***************************************************************************** + .globl Delay + .thumb_func +Delay: + subs r0, #1 + bne Delay + bx lr + +//***************************************************************************** +// +// This is the end of the file. +// +//***************************************************************************** + .end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_rvmdk.S b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_rvmdk.S new file mode 100644 index 0000000000000000000000000000000000000000..f140f61a48251020a9e1220287d769ef283ae499 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_rvmdk.S @@ -0,0 +1,669 @@ +;****************************************************************************** +; +; bl_startup_rvmdk.S - Startup code for RV-MDK. +; +; Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +; Software License Agreement +; +; Texas Instruments (TI) is supplying this software for use solely and +; exclusively on TI's microcontroller products. The software is owned by +; TI and/or its suppliers, and is protected under applicable copyright +; laws. You may not combine this software with "viral" open-source +; software in order to form a larger program. +; +; THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +; NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +; NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +; CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +; DAMAGES, FOR ANY REASON WHATSOEVER. +; +; This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +; +;****************************************************************************** + + include bl_config.inc + +;****************************************************************************** +; +; A couple of defines that would normally be obtained from the appropriate C +; header file, but must be manually provided here since the Keil compiler does +; not have a mechanism for passing assembly source through the C preprocessor. +; +;****************************************************************************** +SYSCTL_RESC equ 0x400fe05c +SYSCTL_RESC_MOSCFAIL equ 0x00010000 +NVIC_VTABLE equ 0xe000ed08 + +;****************************************************************************** +; +; Put the assembler into the correct configuration. +; +;****************************************************************************** + thumb + require8 + preserve8 + +;****************************************************************************** +; +; The stack gets placed into the zero-init section. +; +;****************************************************************************** + area ||.bss||, noinit, align=2 + +;****************************************************************************** +; +; Allocate storage for the stack. +; +;****************************************************************************** +g_pulStack + space _STACK_SIZE * 4 + +;****************************************************************************** +; +; This portion of the file goes into the reset section. +; +;****************************************************************************** + area RESET, code, readonly, align=3 + +;****************************************************************************** +; +; The minimal vector table for a Cortex-M3 processor. +; +;****************************************************************************** + export __Vectors +__Vectors + dcd g_pulStack + (_STACK_SIZE * 4) ; Offset 00: Initial stack pointer + dcd Reset_Handler ; Offset 04: Reset handler + dcd NmiSR ; Offset 08: NMI handler + dcd FaultISR ; Offset 0C: Hard fault handler + dcd IntDefaultHandler ; Offset 10: MPU fault handler + dcd IntDefaultHandler ; Offset 14: Bus fault handler + dcd IntDefaultHandler ; Offset 18: Usage fault handler + dcd 0 ; Offset 1C: Reserved + dcd 0 ; Offset 20: Reserved + dcd 0 ; Offset 24: Reserved + dcd 0 ; Offset 28: Reserved + dcd UpdateHandler ; Offset 2C: SVCall handler + dcd IntDefaultHandler ; Offset 30: Debug monitor handler + dcd 0 ; Offset 34: Reserved + dcd IntDefaultHandler ; Offset 38: PendSV handler + if :def:_ENET_ENABLE_UPDATE + import SysTickIntHandler + dcd SysTickIntHandler ; Offset 3C: SysTick handler + else + dcd IntDefaultHandler ; Offset 3C: SysTick handler + endif + if :def:_UART_ENABLE_UPDATE :land: :def:_UART_AUTOBAUD + import GPIOIntHandler + dcd GPIOIntHandler ; Offset 40: GPIO port A handler + else + dcd IntDefaultHandler ; Offset 40: GPIO port A handler + endif + if :def:_USB_ENABLE_UPDATE :lor: \ + (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + dcd IntDefaultHandler ; Offset 44: GPIO Port B + dcd IntDefaultHandler ; Offset 48: GPIO Port C + dcd IntDefaultHandler ; Offset 4C: GPIO Port D + dcd IntDefaultHandler ; Offset 50: GPIO Port E + dcd IntDefaultHandler ; Offset 54: UART0 Rx and Tx + dcd IntDefaultHandler ; Offset 58: UART1 Rx and Tx + dcd IntDefaultHandler ; Offset 5C: SSI0 Rx and Tx + dcd IntDefaultHandler ; Offset 60: I2C0 Master and Slave + dcd IntDefaultHandler ; Offset 64: PWM Fault + dcd IntDefaultHandler ; Offset 68: PWM Generator 0 + dcd IntDefaultHandler ; Offset 6C: PWM Generator 1 + dcd IntDefaultHandler ; Offset 70: PWM Generator 2 + dcd IntDefaultHandler ; Offset 74: Quadrature Encoder 0 + dcd IntDefaultHandler ; Offset 78: ADC Sequence 0 + dcd IntDefaultHandler ; Offset 7C: ADC Sequence 1 + dcd IntDefaultHandler ; Offset 80: ADC Sequence 2 + dcd IntDefaultHandler ; Offset 84: ADC Sequence 3 + dcd IntDefaultHandler ; Offset 88: Watchdog timer + dcd IntDefaultHandler ; Offset 8C: Timer 0 subtimer A + dcd IntDefaultHandler ; Offset 90: Timer 0 subtimer B + dcd IntDefaultHandler ; Offset 94: Timer 1 subtimer A + dcd IntDefaultHandler ; Offset 98: Timer 1 subtimer B + dcd IntDefaultHandler ; Offset 9C: Timer 2 subtimer A + dcd IntDefaultHandler ; Offset A0: Timer 2 subtimer B + dcd IntDefaultHandler ; Offset A4: Analog Comparator 0 + dcd IntDefaultHandler ; Offset A8: Analog Comparator 1 + dcd IntDefaultHandler ; Offset AC: Analog Comparator 2 + dcd IntDefaultHandler ; Offset B0: System Control + dcd IntDefaultHandler ; Offset B4: FLASH Control + endif + if :def:_USB_ENABLE_UPDATE :lor: \ + (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + dcd IntDefaultHandler ; Offset B8: GPIO Port F + dcd IntDefaultHandler ; Offset BC: GPIO Port G + dcd IntDefaultHandler ; Offset C0: GPIO Port H + dcd IntDefaultHandler ; Offset C4: UART2 Rx and Tx + dcd IntDefaultHandler ; Offset C8: SSI1 Rx and Tx + dcd IntDefaultHandler ; Offset CC: Timer 3 subtimer A + dcd IntDefaultHandler ; Offset D0: Timer 3 subtimer B + dcd IntDefaultHandler ; Offset D4: I2C1 Master and Slave + if :def:_TARGET_IS_TM4C129_RA0 :lor: \ + :def:_TARGET_IS_TM4C129_RA1 :lor: :def:_TARGET_IS_TM4C129_RA2 + dcd IntDefaultHandler ; Offset D8: CAN0 + dcd IntDefaultHandler ; Offset DC: CAN1 + dcd IntDefaultHandler ; Offset E0: Ethernet + dcd IntDefaultHandler ; Offset E4: Hibernation module + if :def:_USB_ENABLE_UPDATE + import USB0DeviceIntHandler + dcd USB0DeviceIntHandler ; Offset E8: USB 0 Controller + else + dcd IntDefaultHandler ; Offset E8: USB 0 Controller + endif + dcd IntDefaultHandler ; Offset EC: PWM Generator 3 + dcd IntDefaultHandler ; Offset F0: uDMA 0 Software + else + dcd IntDefaultHandler ; Offset D8: Quadrature Encoder 1 + dcd IntDefaultHandler ; Offset DC: CAN0 + dcd IntDefaultHandler ; Offset E0: CAN1 + dcd IntDefaultHandler ; Offset E4: CAN2 + dcd IntDefaultHandler ; Offset E8: Ethernet + dcd IntDefaultHandler ; Offset EC: Hibernation module + if :def:_USB_ENABLE_UPDATE + import USB0DeviceIntHandler + dcd USB0DeviceIntHandler ; Offset F0: USB 0 Controller + else + dcd IntDefaultHandler ; Offset F0: USB 0 Controller + endif + endif + endif + +;****************************************************************************** +; +; Initialize the processor by copying the boot loader from flash to SRAM, zero +; filling the .bss section, and moving the vector table to the beginning of +; SRAM. The return address is modified to point to the SRAM copy of the boot +; loader instead of the flash copy, resulting in a branch to the copy now in +; SRAM. +; +;****************************************************************************** + export ProcessorInit +ProcessorInit + ; + ; Copy the code image from flash to SRAM. + ; + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + import ||Image$$SRAM$$ZI$$Base|| + ldr r2, =||Image$$SRAM$$ZI$$Base|| +copy_loop + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + ; + ; Zero fill the .bss section. + ; + movs r0, #0x0000 + import ||Image$$SRAM$$ZI$$Limit|| + ldr r2, =||Image$$SRAM$$ZI$$Limit|| +zero_loop + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + ; + ; Set the vector table pointer to the beginning of SRAM. + ; + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + ; + ; Return to the caller. + ; + bx lr + +;****************************************************************************** +; +; The reset handler, which gets called when the processor starts. +; +;****************************************************************************** + export Reset_Handler +Reset_Handler + + ; + ; Enable the floating-point unit. This must be done here in case any + ; later C functions use floating point. Note that some toolchains will + ; use the FPU registers for general workspace even if no explicit floating + ; point data types are in use. + ; + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, #0x00F00000 + str r1, [r0] + + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the reset handler. + ; + ldr pc, =Reset_Handler_In_SRAM + +;****************************************************************************** +; +; The NMI handler. +; +;****************************************************************************** +NmiSR + if :def:_ENABLE_MOSCFAIL_HANDLER + ; + ; Grab the fault frame from the stack (the stack will be cleared by the + ; processor initialization that follows). + ; + ldm sp, {r4-r11} + mov r12, lr + + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the NMI handler. + ; + ldr pc, =NmiSR_In_SRAM + else + ; + ; Loop forever since there is nothing that we can do about a NMI. + ; + b . + endif + +;****************************************************************************** +; +; The hard fault handler. +; +;****************************************************************************** +FaultISR + ; + ; Loop forever since there is nothing that we can do about a hard fault. + ; + b . + +;****************************************************************************** +; +; The update handler, which gets called when the application would like to +; start an update. +; +;****************************************************************************** +UpdateHandler + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the update handler. + ; + ldr pc, =UpdateHandler_In_SRAM + +;****************************************************************************** +; +; This portion of the file goes into the text section. +; +;****************************************************************************** + align 4 + area ||.text||, code, readonly, align=2 + +Reset_Handler_In_SRAM + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + import $_BL_HW_INIT_FN_HOOK + bl $_BL_HW_INIT_FN_HOOK + endif + + ; + ; See if an update should be performed. + ; + import CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + ; + ; Configure the microcontroller. + ; +EnterBootLoader + if :def:_ENET_ENABLE_UPDATE + import ConfigureEnet + bl ConfigureEnet + elif :def:_CAN_ENABLE_UPDATE + import ConfigureCAN + bl ConfigureCAN + elif :def:_USB_ENABLE_UPDATE + import ConfigureUSB + bl ConfigureUSB + else + import ConfigureDevice + bl ConfigureDevice + endif + + ; + ; Call the user-supplied initialization function if provided. + ; + if :def:_BL_INIT_FN_HOOK + import $_BL_INIT_FN_HOOK + bl $_BL_INIT_FN_HOOK + endif + + ; + ; Branch to the update handler. + ; + if :def:_ENET_ENABLE_UPDATE + import UpdateBOOTP + b UpdateBOOTP + elif :def:_CAN_ENABLE_UPDATE + import UpdaterCAN + b UpdaterCAN + elif :def:_USB_ENABLE_UPDATE + import UpdaterUSB + b UpdaterUSB + else + import Updater + b Updater + endif + + ; + ; This is a second symbol to allow starting the application from the boot + ; loader the linker may not like the perceived jump. + ; + export StartApplication +StartApplication + ; + ; Call the application via the reset handler in its vector table. Load the + ; address of the application vector table. + ; +CallApplication + ; + ; Copy the application's vector table to the target address if necessary. + ; Note that incorrect boot loader configuration could cause this to + ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ; of SRAM) is safe since this will use the same memory that the boot loader + ; already uses for its vector table. Great care will have to be taken if + ; other addresses are to be used. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r1, #(_APP_START_ADDRESS >> 16) + endif + + ; + ; Calculate the end address of the vector table assuming that it has the + ; maximum possible number of vectors. We don't know how many the app has + ; populated so this is the safest approach though it may copy some non + ; vector data if the app table is smaller than the maximum. + ; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop + endif + + ; + ; Set the vector table address to the beginning of the application. + ; + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ; + ; Load the stack pointer from the application's vector table. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r0, #(_APP_START_ADDRESS >> 16) + endif + endif + ldr sp, [r0] + + ; + ; Load the initial PC from the application's vector table and branch to + ; the application's entry point. + ; + ldr r0, [r0, #4] + bx r0 + +;****************************************************************************** +; +; The update handler, which gets called when the application would like to +; start an update. +; +;****************************************************************************** +UpdateHandler_In_SRAM + ; + ; Load the stack pointer from the vector table. + ; + movs r0, #0x0000 + ldr sp, [r0] + + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + bl $_BL_HW_INIT_FN_HOOK + endif + + ; + ; Call the user-supplied re-initialization function if provided. + ; + if :def:_BL_REINIT_FN_HOOK + import $_BL_REINIT_FN_HOOK + bl $_BL_REINIT_FN_HOOK + endif + + ; + ; Branch to the update handler. + ; + if :def:_ENET_ENABLE_UPDATE + b UpdateBOOTP + elif :def:_CAN_ENABLE_UPDATE + import AppUpdaterCAN + b AppUpdaterCAN + elif :def:_USB_ENABLE_UPDATE + import AppUpdaterUSB + b AppUpdaterUSB + else + b Updater + endif + +;****************************************************************************** +; +; The NMI handler. +; +;****************************************************************************** + if :def:_ENABLE_MOSCFAIL_HANDLER +NmiSR_In_SRAM + ; + ; Restore the stack frame. + ; + mov lr, r12 + stm sp, {r4-r11} + + ; + ; Save the link register. + ; + mov r9, lr + + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + bl _BL_HW_INIT_FN_HOOK + endif + + ; + ; See if an update should be performed. + ; + bl CheckForceUpdate + cbz r0, EnterApplication + + ; + ; Clear the MOSCFAIL bit in RESC. + ; + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + ; + ; Fix up the PC on the stack so that the boot pin check is bypassed + ; (since it has already been performed). + ; + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + ; + ; Return from the NMI handler. This will then start execution of the + ; boot loader. + ; + bx r9 + + ; + ; Restore the link register. + ; +EnterApplication + mov lr, r9 + + ; + ; Copy the application's vector table to the target address if necessary. + ; Note that incorrect boot loader configuration could cause this to + ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ; of SRAM) is safe since this will use the same memory that the boot loader + ; already uses for its vector table. Great care will have to be taken if + ; other addresses are to be used. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r1, #(_APP_START_ADDRESS >> 16) + endif + + ; + ; Calculate the end address of the vector table assuming that it has the + ; maximum possible number of vectors. We don't know how many the app has + ; populated so this is the safest approach though it may copy some non + ; vector data if the app table is smaller than the maximum. + ; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2 + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 + endif + + ; + ; Set the application's vector table start address. Typically this is the + ; application start address but in some cases an application may relocate + ; this so we can't assume that these two addresses are equal. + ; + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ; + ; Remove the NMI stack frame from the boot loader's stack. + ; + ldmia sp, {r4-r11} + + ; + ; Get the application's stack pointer. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r0, #(_APP_START_ADDRESS >> 16) + endif + endif + ldr sp, [r0, #0x00] + + ; + ; Fix up the NMI stack frame's return address to be the reset handler of + ; the application. + ; + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + ; + ; Store the NMI stack frame onto the application's stack. + ; + stmdb sp!, {r4-r11} + + ; + ; Branch to the application's NMI handler. + ; + ldr r0, [r0, #0x08] + bx r0 + endif + +;****************************************************************************** +; +; The default interrupt handler. +; +;****************************************************************************** +IntDefaultHandler + ; + ; Loop forever since there is nothing that we can do about an unexpected + ; interrupt. + ; + b . + +;****************************************************************************** +; +; Provides a small delay. The loop below takes 3 cycles/loop. +; +;****************************************************************************** + export Delay +Delay + subs r0, #1 + bne Delay + bx lr + +;****************************************************************************** +; +; This is the end of the file. +; +;****************************************************************************** + align 4 + end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_sourcerygxx.S b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_sourcerygxx.S new file mode 100644 index 0000000000000000000000000000000000000000..bfe8714e4b35115509d2a69a7fa26dca8e3edf5e --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_startup_sourcerygxx.S @@ -0,0 +1,646 @@ +//***************************************************************************** +// +// bl_startup_sourcerygxx.S - Startup code for Sourcery G++. +// +// Copyright (c) 2007-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +//***************************************************************************** +// +// Include the assember definitions used to make this code compiler +// independent. +// +//***************************************************************************** +#include "inc/hw_nvic.h" +#include "inc/hw_sysctl.h" +#include "bl_config.h" + +//***************************************************************************** +// +// Put the assembler into the correct configuration. +// +//***************************************************************************** + .syntax unified + .thumb + +//***************************************************************************** +// +// The stack gets placed into the zero-init section. +// +//***************************************************************************** + .bss + +//***************************************************************************** +// +// Allocate storage for the stack. +// +//***************************************************************************** +g_pulStack: + .space STACK_SIZE * 4 + +//***************************************************************************** +// +// This portion of the file goes into the text section. +// +//***************************************************************************** + .section .isr_vector + +//***************************************************************************** +// +// The minimal vector table for a Cortex-M3 processor. +// +//***************************************************************************** +Vectors: + .word g_pulStack + (STACK_SIZE * 4) // Offset 00: Initial stack pointer + .word ResetISR - 0x20000000 // Offset 04: Reset handler + .word NmiSR - 0x20000000 // Offset 08: NMI handler + .word FaultISR - 0x20000000 // Offset 0C: Hard fault handler + .word IntDefaultHandler // Offset 10: MPU fault handler + .word IntDefaultHandler // Offset 14: Bus fault handler + .word IntDefaultHandler // Offset 18: Usage fault handler + .word 0 // Offset 1C: Reserved + .word 0 // Offset 20: Reserved + .word 0 // Offset 24: Reserved + .word 0 // Offset 28: Reserved + .word UpdateHandler - 0x20000000 // Offset 2C: SVCall handler + .word IntDefaultHandler // Offset 30: Debug monitor handler + .word 0 // Offset 34: Reserved + .word IntDefaultHandler // Offset 38: PendSV handler +#if defined(ENET_ENABLE_UPDATE) + .extern SysTickIntHandler + .word SysTickIntHandler // Offset 3C: SysTick handler +#else + .word IntDefaultHandler // Offset 3C: SysTick handler +#endif +#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) + .extern GPIOIntHandler + .word GPIOIntHandler // Offset 40: GPIO port A handler +#else + .word IntDefaultHandler // Offset 40: GPIO port A handler +#endif +#if (defined(USB_ENABLE_UPDATE) || \ + (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler // Offset 44: GPIO Port B + .word IntDefaultHandler // Offset 48: GPIO Port C + .word IntDefaultHandler // Offset 4C: GPIO Port D + .word IntDefaultHandler // Offset 50: GPIO Port E + .word IntDefaultHandler // Offset 54: UART0 Rx and Tx + .word IntDefaultHandler // Offset 58: UART1 Rx and Tx + .word IntDefaultHandler // Offset 5C: SSI0 Rx and Tx + .word IntDefaultHandler // Offset 60: I2C0 Master and Slave + .word IntDefaultHandler // Offset 64: PWM Fault + .word IntDefaultHandler // Offset 68: PWM Generator 0 + .word IntDefaultHandler // Offset 6C: PWM Generator 1 + .word IntDefaultHandler // Offset 70: PWM Generator 2 + .word IntDefaultHandler // Offset 74: Quadrature Encoder 0 + .word IntDefaultHandler // Offset 78: ADC Sequence 0 + .word IntDefaultHandler // Offset 7C: ADC Sequence 1 + .word IntDefaultHandler // Offset 80: ADC Sequence 2 + .word IntDefaultHandler // Offset 84: ADC Sequence 3 + .word IntDefaultHandler // Offset 88: Watchdog timer + .word IntDefaultHandler // Offset 8C: Timer 0 subtimer A + .word IntDefaultHandler // Offset 90: Timer 0 subtimer B + .word IntDefaultHandler // Offset 94: Timer 1 subtimer A + .word IntDefaultHandler // Offset 98: Timer 1 subtimer B + .word IntDefaultHandler // Offset 9C: Timer 2 subtimer A + .word IntDefaultHandler // Offset A0: Timer 2 subtimer B + .word IntDefaultHandler // Offset A4: Analog Comparator 0 + .word IntDefaultHandler // Offset A8: Analog Comparator 1 + .word IntDefaultHandler // Offset AC: Analog Comparator 2 + .word IntDefaultHandler // Offset B0: System Control + .word IntDefaultHandler // Offset B4: FLASH Control +#endif +#if (defined(USB_ENABLE_UPDATE) || (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler // Offset B8: GPIO Port F + .word IntDefaultHandler // Offset BC: GPIO Port G + .word IntDefaultHandler // Offset C0: GPIO Port H + .word IntDefaultHandler // Offset C4: UART2 Rx and Tx + .word IntDefaultHandler // Offset C8: SSI1 Rx and Tx + .word IntDefaultHandler // Offset CC: Timer 3 subtimer A + .word IntDefaultHandler // Offset D0: Timer 3 subtimer B + .word IntDefaultHandler // Offset D4: I2C1 Master and Slave +#if (defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || + defined(TARGET_IS_TM4C129_RA2)) + .word IntDefaultHandler // Offset D8: CAN0 + .word IntDefaultHandler // Offset DC: CAN1 + .word IntDefaultHandler // Offset E0: Ethernet + .word IntDefaultHandler // Offset E4: Hibernation module +#if defined(USB_ENABLE_UPDATE) + .extern USB0DeviceIntHandler + .word USB0DeviceIntHandler // Offset E8: USB 0 Controller +#else + .word IntDefaultHandler // Offset E8: USB 0 Controller +#endif + .word IntDefaultHandler // Offset EC: PWM Generator 3 + .word IntDefaultHandler // Offset F0: uDMA 0 Software +#else + .word IntDefaultHandler // Offset D8: Quadrature Encoder 1 + .word IntDefaultHandler // Offset DC: CAN0 + .word IntDefaultHandler // Offset E0: CAN1 + .word IntDefaultHandler // Offset E4: CAN2 + .word IntDefaultHandler // Offset E8: Ethernet + .word IntDefaultHandler // Offset EC: Hibernation module +#if defined(USB_ENABLE_UPDATE) + .extern USB0DeviceIntHandler + .word USB0DeviceIntHandler // Offset F0: USB 0 Controller +#else + .word IntDefaultHandler // Offset F0: USB 0 Controller +#endif +#endif +#endif + +//***************************************************************************** +// +// This portion of the file goes into the text section. +// +//***************************************************************************** + .text + +//***************************************************************************** +// +// Initialize the processor by copying the boot loader from flash to SRAM, zero +// filling the .bss section, and moving the vector table to the beginning of +// SRAM. The return address is modified to point to the SRAM copy of the boot +// loader instead of the flash copy, resulting in a branch to the copy now in +// SRAM. +// +//***************************************************************************** + .thumb_func +ProcessorInit: + // + // Copy the code image from flash to SRAM. + // + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + .extern _bss + ldr r2, =_bss +copy_loop: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + // + // Zero fill the .bss section. + // + movs r0, #0x0000 + .extern _ebss + ldr r2, =_ebss +zero_loop: + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + // + // Set the vector table pointer to the beginning of SRAM. + // + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + // + // Set the return address to the code just copied into SRAM. + // + orr lr, lr, #0x20000000 + + // + // Return to the caller. + // + bx lr + +//***************************************************************************** +// +// The reset handler, which gets called when the processor starts. +// +//***************************************************************************** + .globl ResetISR + .thumb_func +ResetISR: + // + // Enable the floating-point unit. This must be done here in case any + // later C functions use floating point. Note that some toolchains will + // use the FPU registers for general workspace even if no explicit floating + // point data types are in use. + // + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, r1, #0x00F00000 + str r1, [r0] + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + .extern BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + .extern CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + // + // Configure the microcontroller. + // + .thumb_func +EnterBootLoader: +#ifdef ENET_ENABLE_UPDATE + .extern ConfigureEnet + bl ConfigureEnet +#elif defined(CAN_ENABLE_UPDATE) + .extern ConfigureCAN + bl ConfigureCAN +#elif defined(USB_ENABLE_UPDATE) + .extern ConfigureUSB + bl ConfigureUSB +#else + .extern ConfigureDevice + bl ConfigureDevice +#endif + + // + // Call the user-supplied initialization function if provided. + // +#ifdef BL_INIT_FN_HOOK + .extern BL_INIT_FN_HOOK + bl BL_INIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + .extern UpdateBOOTP + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + .extern UpdaterCAN + b UpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + .extern UpdaterUSB + b UpdaterUSB +#else + .extern Updater + b Updater +#endif + + // + // This is a second symbol to allow starting the application from the boot + // loader the linker may not like the perceived jump. + // + .globl StartApplication + .thumb_func +StartApplication: + // + // Call the application via the reset handler in its vector table. Load + // the address of the application vector table. + // + .thumb_func +CallApplication: + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Load the stack pointer from the application's vector table. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0] + + // + // Load the initial PC from the application's vector table and branch to + // the application's entry point. + // + ldr r0, [r0, #4] + bx r0 + +//***************************************************************************** +// +// The update handler, which gets called when the application would like to +// start an update. +// +//***************************************************************************** + .thumb_func +UpdateHandler: + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Load the stack pointer from the vector table. + // + movs r0, #0x0000 + ldr sp, [r0] + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // Call the user-supplied re-initialization function if provided. + // +#ifdef BL_REINIT_FN_HOOK + .extern BL_REINIT_FN_HOOK + bl BL_REINIT_FN_HOOK +#endif + + // + // Branch to the update handler. + // +#ifdef ENET_ENABLE_UPDATE + b UpdateBOOTP +#elif defined(CAN_ENABLE_UPDATE) + .extern AppUpdaterCAN + b AppUpdaterCAN +#elif defined(USB_ENABLE_UPDATE) + .extern AppUpdaterUSB + b AppUpdaterUSB +#else + b Updater +#endif + +//***************************************************************************** +// +// The NMI handler. +// +//***************************************************************************** + .thumb_func +NmiSR: +#ifdef ENABLE_MOSCFAIL_HANDLER + // + // Grab the fault frame from the stack (the stack will be cleared by the + // processor initialization that follows). + // + ldm sp, {r4-r11} + mov r12, lr + + // + // Initialize the processor. + // + bl ProcessorInit + + // + // Restore the stack frame. + // + mov lr, r12 + stm sp, {r4-r11} + + // + // Save the link register. + // + mov r9, lr + + // + // Call the user-supplied low level hardware initialization function + // if provided. + // +#ifdef BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK +#endif + + // + // See if an update should be performed. + // + bl CheckForceUpdate + cbz r0, EnterApplication + + // + // Clear the MOSCFAIL bit in RESC. + // + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + // + // Fix up the PC on the stack so that the boot pin check is bypassed + // (since it has already been performed). + // + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + // + // Return from the NMI handler. This will then start execution of the + // boot loader. + // + bx r9 + + // + // Restore the link register. + // + .thumb_func +EnterApplication: + mov lr, r9 + + // + // Copy the application's vector table to the target address if necessary. + // Note that incorrect boot loader configuration could cause this to + // corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + // of SRAM) is safe since this will use the same memory that the boot + // loader already uses for its vector table. Great care will have to be + // taken if other addresses are to be used. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r1, #(APP_START_ADDRESS >> 16) +#endif + + // + // Calculate the end address of the vector table assuming that it has the + // maximum possible number of vectors. We don't know how many the app has + // populated so this is the safest approach though it may copy some non + // vector data if the app table is smaller than the maximum. + // + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 +#endif + + // + // Set the application's vector table start address. Typically this is the + // application start address but in some cases an application may relocate + // this so we can't assume that these two addresses are equal. + // + movw r0, #(VTABLE_START_ADDRESS & 0xffff) +#if (VTABLE_START_ADDRESS > 0xffff) + movt r0, #(VTABLE_START_ADDRESS >> 16) +#endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + // + // Remove the NMI stack frame from the boot loader's stack. + // + ldmia sp, {r4-r11} + + // + // Get the application's stack pointer. + // +#if (APP_START_ADDRESS != VTABLE_START_ADDRESS) + movw r0, #(APP_START_ADDRESS & 0xffff) +#if (APP_START_ADDRESS > 0xffff) + movt r0, #(APP_START_ADDRESS >> 16) +#endif +#endif + ldr sp, [r0, #0x00] + + // + // Fix up the NMI stack frame's return address to be the reset handler of + // the application. + // + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + // + // Store the NMI stack frame onto the application's stack. + // + stmdb sp!, {r4-r11} + + // + // Branch to the application's NMI handler. + // + ldr r0, [r0, #0x08] + bx r0 +#else + // + // Loop forever since there is nothing that we can do about a NMI. + // + b . +#endif + +//***************************************************************************** +// +// The hard fault handler. +// +//***************************************************************************** + .thumb_func +FaultISR: + // + // Loop forever since there is nothing that we can do about a hard fault. + // + b . + +//***************************************************************************** +// +// The default interrupt handler. +// +//***************************************************************************** + .thumb_func +IntDefaultHandler: + // + // Loop forever since there is nothing that we can do about an unexpected + // interrupt. + // + b . + +//***************************************************************************** +// +// Provides a small delay. The loop below takes 3 cycles/loop. +// +//***************************************************************************** + .globl Delay + .thumb_func +Delay: + subs r0, #1 + bne Delay + bx lr + +//***************************************************************************** +// +// This is the end of the file. +// +//***************************************************************************** + .end diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..811d93621d45c722ac49f9a2c3fecf6f2b255bfd --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.c @@ -0,0 +1,156 @@ +//***************************************************************************** +// +// bl_uart.c - Functions to transfer data via the UART port. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "inc/hw_uart.h" +#include "bl_config.h" +#include "boot_loader/bl_uart.h" + +//***************************************************************************** +// +//! \addtogroup bl_uart_api +//! @{ +// +//***************************************************************************** +#if defined(UART_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +//! Sends data over the UART port. +//! +//! \param pui8Data is the buffer containing the data to write out to the UART +//! port. +//! \param ui32Size is the number of bytes provided in \e pui8Data buffer that +//! will be written out to the UART port. +//! +//! This function sends \e ui32Size bytes of data from the buffer pointed to by +//! \e pui8Data via the UART port. +//! +//! \return None. +// +//***************************************************************************** +void +UARTSend(const uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Transmit the number of bytes requested on the UART port. + // + while(ui32Size--) + { + // + // Make sure that the transmit FIFO is not full. + // + while((HWREG(UARTx_BASE + UART_O_FR) & UART_FR_TXFF)) + { + } + + // + // Send out the next byte. + // + HWREG(UARTx_BASE + UART_O_DR) = *pui8Data++; + } + + // + // Wait until the UART is done transmitting. + // + UARTFlush(); +} + +//***************************************************************************** +// +//! Waits until all data has been transmitted by the UART port. +//! +//! This function waits until all data written to the UART port has been +//! transmitted. +//! +//! \return None. +// +//***************************************************************************** +void +UARTFlush(void) +{ + // + // Wait for the UART FIFO to empty and then wait for the shifter to get the + // bytes out the port. + // + while(!(HWREG(UARTx_BASE + UART_O_FR) & UART_FR_TXFE)) + { + } + + // + // Wait for the FIFO to not be busy so that the shifter completes. + // + while((HWREG(UARTx_BASE + UART_O_FR) & UART_FR_BUSY)) + { + } +} + +//***************************************************************************** +// +//! Receives data over the UART port. +//! +//! \param pui8Data is the buffer to read data into from the UART port. +//! \param ui32Size is the number of bytes provided in the \e pui8Data buffer +//! that should be written with data from the UART port. +//! +//! This function reads back \e ui32Size bytes of data from the UART port, into +//! the buffer that is pointed to by \e pui8Data. This function will not +//! return until \e ui32Size number of bytes have been received. +//! +//! \return None. +// +//***************************************************************************** +void +UARTReceive(uint8_t *pui8Data, uint32_t ui32Size) +{ + // + // Send out the number of bytes requested. + // + while(ui32Size--) + { + // + // Wait for the FIFO to not be empty. + // + while((HWREG(UARTx_BASE + UART_O_FR) & UART_FR_RXFE)) + { + } + + // + // Receive a byte from the UART. + // + *pui8Data++ = HWREG(UARTx_BASE + UART_O_DR); + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** +#endif diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.h b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..d389a707af25f27308d602ca4545cc08f7b4a519 --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_uart.h @@ -0,0 +1,133 @@ +//***************************************************************************** +// +// bl_uart.h - Definitions for the UART transport functions. +// +// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#ifndef __BL_UART_H__ +#define __BL_UART_H__ + +//***************************************************************************** +// +// This section maps the defines to default for UART Boot Loader for legacy +// projects +// +//***************************************************************************** +#ifndef UART_CLOCK_ENABLE +#define UART_CLOCK_ENABLE SYSCTL_RCGCUART_R0 +#endif + +#ifndef UARTx_BASE +#define UARTx_BASE UART0_BASE +#endif + +#ifndef UART_RXPIN_CLOCK_ENABLE +#define UART_RXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef UART_RXPIN_BASE +#define UART_RXPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef UART_RXPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define UART_RXPIN_PCTL 0x1 +#else +#define UART_RXPIN_PCTL 0x1 +#endif +#endif + +#ifndef UART_RXPIN_POS +#define UART_RXPIN_POS 0 +#endif + +#ifndef UART_TXPIN_CLOCK_ENABLE +#define UART_TXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0 +#endif + +#ifndef UART_TXPIN_BASE +#define UART_TXPIN_BASE GPIO_PORTA_BASE +#endif + +#ifndef UART_TXPIN_PCTL +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) +#define UART_TXPIN_PCTL 0x1 +#else +#define UART_TXPIN_PCTL 0x1 +#endif +#endif + +#ifndef UART_TXPIN_POS +#define UART_TXPIN_POS 1 +#endif + +//***************************************************************************** +// +// This macro is used to generate a constant to represent the UART baud rate to +// processor clock rate ratio. This prevents the need for run-time calculation +// of the ratio of baud rate to processor clock rate ratio. +// +//***************************************************************************** +#define UART_BAUD_RATIO(ui32Baud) \ + ((((CRYSTAL_FREQ * 8) / ui32Baud) + 1) / 2) + +//***************************************************************************** +// +// This defines the UART receive pin that is being used by the boot loader. +// +//***************************************************************************** +#define UART_RX (1 << UART_RXPIN_POS) +#define UART_RX_PCTL (UART_RXPIN_PCTL << (4 * UART_RXPIN_POS)) + +//***************************************************************************** +// +// This defines the UART transmit pin that is being used by the boot loader. +// +//***************************************************************************** +#define UART_TX (1 << UART_TXPIN_POS) +#define UART_TX_PCTL (UART_TXPIN_PCTL << (4 * UART_TXPIN_POS)) + +//***************************************************************************** +// +// UART Transport APIs +// +//***************************************************************************** +extern void UARTSend(const uint8_t *pui8Data, uint32_t ui32Size); +extern void UARTReceive(uint8_t *pui8Data, uint32_t ui32Size); +extern void UARTFlush(void); +extern int UARTAutoBaud(uint32_t *pui32Ratio); + +//***************************************************************************** +// +// Define the transport functions if the UART is being used. +// +//***************************************************************************** +#ifdef UART_ENABLE_UPDATE +#define SendData UARTSend +#define FlushData UARTFlush +#define ReceiveData UARTReceive +#endif + +#endif // __BL_UART_H__ diff --git a/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_usb.c b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..313d135880cd4b3616563d2b7bf3fa29585dd37b --- /dev/null +++ b/Aufgabenstellung und Unterlagen/TivaWare_C_Series-2.1.4.178/boot_loader/bl_usb.c @@ -0,0 +1,2345 @@ +//***************************************************************************** +// +// bl_usb.c - Functions to transfer data via the USB port. +// +// Copyright (c) 2009-2017 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_flash.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "inc/hw_nvic.h" +#include "inc/hw_usb.h" +#include "bl_config.h" +#include "boot_loader/bl_crystal.h" +#include "boot_loader/bl_flash.h" +#include "boot_loader/bl_hooks.h" +#include "boot_loader/bl_usbfuncs.h" +#include "boot_loader/usbdfu.h" + +//***************************************************************************** +// +// DFU Notes: +// +// 1. This implementation is manifestation-tolerant and doesn't time out +// waiting for a reset after a download completes. As a result, the detach +// timeout in the DFU functional descriptor is set to the maximum possible +// value representing a timeout of 65.536 seconds. +// +// 2. This implementation does not support the BUSY state. By skipping this +// and remaining in DNLOAD_SYNC when we are waiting for a programming or +// erase operation to complete, we save the overhead of having to support a +// timeout mechanism. Host-side implementations don't seem to rely upon +// the busy state so this does not appear to be a problem. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup bl_usb_api +//! @{ +// +//***************************************************************************** +#if defined(USB_ENABLE_UPDATE) || defined(DOXYGEN) + +//***************************************************************************** +// +// Make sure that the crystal frequency is defined. +// +//***************************************************************************** +#if !defined(CRYSTAL_FREQ) +#error ERROR: CRYSTAL_FREQ must be defined for USB update! +#endif + +//***************************************************************************** +// +// Make sure that the crystal frequency is one of the ones that support USB +// operation. +// +//***************************************************************************** +#if CRYSTAL_FREQ != 5000000 && \ + CRYSTAL_FREQ != 6000000 && \ + CRYSTAL_FREQ != 8000000 && \ + CRYSTAL_FREQ != 10000000 && \ + CRYSTAL_FREQ != 12000000 && \ + CRYSTAL_FREQ != 16000000 && \ + CRYSTAL_FREQ != 25000000 +#error ERROR: Invalid CRYSTAL_FREQ specified for USB update! +#endif + +//***************************************************************************** +// +// The DFU device information structure was developed assuming flash block +// sizes in the 1KB to 32KB range but large external flash devices may have +// 64KB or larger blocks. If the configuration options indicate a target +// device with large pages, we fake the size at 32KB to keep the client happy. +// The other option would be to redefine this field as an uint32_t but that +// would break existing applications using the interface. +// +// For normal operation, this is unlikely to cause a problem since we will not +// allow a flash operation to start anywhere other than at APP_START_ADDRESS +// (which must fall on a real flash page boundary) or the start of the +// reserved +// +//***************************************************************************** +#if (FLASH_PAGE_SIZE > 0x10000) +#define DFU_REPORTED_PAGE_SIZE 0x8000 +#else +#define DFU_REPORTED_PAGE_SIZE FLASH_PAGE_SIZE +#endif + +//***************************************************************************** +// +// This holds the total size of the firmware image being downloaded (which is +// needed if we have a progress reporting hook function provided). +// +//***************************************************************************** +#ifdef BL_PROGRESS_FN_HOOK +uint32_t g_ui32ImageSize; +#endif + +//***************************************************************************** +// +// The structure used to define a block of memory. +// +//***************************************************************************** +typedef struct +{ + uint8_t *pui8Start; + uint32_t ui32Length; +} +tMemoryBlock; + +//***************************************************************************** +// +// The block of memory that is to be sent back in response to the next upload +// request. +// +//***************************************************************************** +tMemoryBlock g_sNextUpload; + +//***************************************************************************** +// +// The block of memory into which the next programming operation will write. +// +//***************************************************************************** +volatile tMemoryBlock g_sNextDownload; + +//***************************************************************************** +// +// The block of flash to be erased. +// +//***************************************************************************** +volatile tMemoryBlock g_sErase; + +//***************************************************************************** +// +// Information on the device we are running on. This will be returned to the +// host after a download request containing command DFU_CMD_INFO. +// +//***************************************************************************** +tDFUDeviceInfo g_sDFUDeviceInfo; + +//***************************************************************************** +// +// This variable keeps track of the last software-specific command received +// from the host via a download request. +// +//***************************************************************************** +uint8_t g_ui8LastCommand; + +//***************************************************************************** +// +// The current status of the DFU device as reported to the host in response to +// USBD_DFU_REQUEST_GETSTATUS. +// +//***************************************************************************** +tDFUGetStatusResponse g_sDFUStatus = +{ + 0, { 5, 0, 0 }, (uint8_t)STATE_IDLE, 0 +}; + +//***************************************************************************** +// +// The structure sent in response to a valid USBD_DFU_REQUEST_TIVA. +// +//***************************************************************************** +tDFUQueryTIVAProtocol g_sDFUProtocol = +{ + DFU_PROTOCOL_USBLIB_MARKER, + DFU_PROTOCOL_USBLIB_VERSION_1 +}; + +//***************************************************************************** +// +// The current state of the device. +// +//***************************************************************************** +volatile tDFUState g_eDFUState = STATE_IDLE; + +//***************************************************************************** +// +// The current status of the device. +// +//***************************************************************************** +volatile tDFUStatus g_eDFUStatus = STATUS_OK; + +//***************************************************************************** +// +// The buffer used to hold download data from the host prior to writing it to +// flash or image data in the process of being uploaded to the host. +// +//***************************************************************************** +uint8_t g_pui8DFUBuffer[DFU_TRANSFER_SIZE]; + +//***************************************************************************** +// +// The start of the image data within g_pui8DFUBuffer. +// +//***************************************************************************** +uint8_t *g_pui8DFUWrite; + +//***************************************************************************** +// +// The number of bytes of valid data in the DFU buffer. +// +//***************************************************************************** +volatile uint16_t g_ui16DFUBufferUsed; + +//***************************************************************************** +// +// Flags used to indicate that the main thread is being asked to do something. +// +//***************************************************************************** +volatile uint32_t g_ui32CommandFlags; +#define CMD_FLAG_ERASE 0 +#define CMD_FLAG_WRITE 1 +#define CMD_FLAG_RESET 2 + +//***************************************************************************** +// +// This global determines whether or not we add a DFU header to any uploaded +// image data. If true, the binary image is sent without the header. If false +// the header is included. This is a DFU requirement since uploaded images +// must be able to be downloaded again and hence must have the header in place +// so that the destination address is available. +// +//***************************************************************************** +bool g_bUploadBinary = false; + +//***************************************************************************** +// +// If the upload format includes the header, we need to be able to suppress +// this when replying to TIVA-specific commands such as CMD_DFU_INFO. This +// global determines whether we need to suppress the header that would +// otherwise be send in response to the first USBD_DFU_REQUEST_UPLOAD received +// while in STATE_IDLE. +// +//***************************************************************************** +bool g_bSuppressUploadHeader = false; + +//***************************************************************************** +// +// A flag we use to indicate when the device has been enumerated. +// +//***************************************************************************** +bool g_bAddressSet = false; + +//***************************************************************************** +// +// The languages supported by this device. +// +//***************************************************************************** +const uint8_t g_pui8LangDescriptor[] = +{ + 4, + USB_DTYPE_STRING, + USBShort(USB_LANG_EN_US) +}; + +//***************************************************************************** +// +// The jump table used to implement request handling in the DFU state machine. +// +//***************************************************************************** +typedef void (* tHandleRequests)(tUSBRequest *psUSBRequest); + +extern void HandleRequestIdle(tUSBRequest *psUSBRequest); +extern void HandleRequestDnloadSync(tUSBRequest *psUSBRequest); +extern void HandleRequestDnloadIdle(tUSBRequest *psUSBRequest); +extern void HandleRequestManifestSync(tUSBRequest *psUSBRequest); +extern void HandleRequestUploadIdle(tUSBRequest *psUSBRequest); +extern void HandleRequestError(tUSBRequest *psUSBRequest); + +tHandleRequests g_pfnRequestHandlers[] = +{ + 0, // STATE_APP_IDLE + 0, // STATE_APP_DETACH + HandleRequestIdle, // STATE_IDLE + HandleRequestDnloadSync, // STATE_DNLOAD_SYNC + HandleRequestDnloadSync, // STATE_DNBUSY + HandleRequestDnloadIdle, // STATE_DNLOAD_IDLE + HandleRequestManifestSync, // STATE_MANIFEST_SYNC + 0, // STATE_MANIFEST + 0, // STATE_MANIFEST_WAIT_RESET + HandleRequestUploadIdle, // STATE_UPLOAD_IDLE + HandleRequestError // STATE_ERROR +}; + +//***************************************************************************** +// +// The manufacturer string. +// +//***************************************************************************** +const uint8_t g_pui8ManufacturerString[] = +{ + (17 + 1) * 2, + USB_DTYPE_STRING, + 'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, + 's', 0, 't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, + 's', 0 +}; + +//***************************************************************************** +// +// The product string. +// +//***************************************************************************** +const uint8_t g_pui8ProductString[] = +{ + (23 + 1) * 2, + USB_DTYPE_STRING, + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, ' ', 0, 'F', 0, 'i', 0, + 'r', 0, 'm', 0, 'w', 0, 'a', 0, 'r', 0, 'e', 0, ' ', 0, 'U', 0, 'p', 0, + 'g', 0, 'r', 0, 'a', 0, 'd', 0, 'e', 0 +}; + +//***************************************************************************** +// +// The serial number string. +// +//***************************************************************************** +const uint8_t g_pui8SerialNumberString[] = +{ + (3 + 1) * 2, + USB_DTYPE_STRING, + '0', 0, '.', 0, '1', 0 +}; + +//***************************************************************************** +// +// The descriptor string table. +// +//***************************************************************************** +const uint8_t *const g_ppui8StringDescriptors[] = +{ + g_pui8LangDescriptor, + g_pui8ManufacturerString, + g_pui8ProductString, + g_pui8SerialNumberString +}; + +//***************************************************************************** +// +// DFU Device Descriptor. +// +//***************************************************************************** +const uint8_t g_pui8DFUDeviceDescriptor[] = +{ + 18, // Size of this structure. + USB_DTYPE_DEVICE, // Type of this structure. + USBShort(0x110), // USB version 1.1 (if we say 2.0, hosts assume + // high-speed - see USB 2.0 spec 9.2.6.6) + USB_CLASS_VEND_SPECIFIC, // USB Device Class + 0, // USB Device Sub-class + 0, // USB Device protocol + 64, // Maximum packet size for default pipe. + USBShort(USB_VENDOR_ID), // Vendor ID (VID). + USBShort(USB_PRODUCT_ID), // Product ID (PID). + USBShort(USB_DEVICE_ID), // Device Release Number BCD. + 1, // Manufacturer string identifier. + 2, // Product string identifier. + 3, // Product serial number. + 1 // Number of configurations. +}; + +//***************************************************************************** +// +// DFU device configuration descriptor. +// +//***************************************************************************** +const uint8_t g_pui8DFUConfigDescriptor[] = +{ + // + // Configuration descriptor header. + // + 9, // Size of the configuration descriptor. + USB_DTYPE_CONFIGURATION, // Type of this descriptor. + USBShort(27), // The total size of this full structure. + 1, // The number of interfaces in this + // configuration. + 1, // The unique value for this configuration. + 0, // The string identifier that describes this + // configuration. +#if USB_BUS_POWERED + USB_CONF_ATTR_BUS_PWR, // Bus Powered +#else + USB_CONF_ATTR_SELF_PWR, // Self Powered +#endif + (USB_MAX_POWER / 2), // The maximum power in 2mA increments. + + // + // Interface descriptor. + // + 9, // Length of this descriptor. + USB_DTYPE_INTERFACE, // This is an interface descriptor. + 0, // Interface number . + 0, // Alternate setting number. + 0, // Number of endpoints (only endpoint 0 used) + USB_CLASS_APP_SPECIFIC, // Application specific interface class + USB_DFU_SUBCLASS, // Device Firmware Upgrade subclass + USB_DFU_PROTOCOL, // DFU protocol + 0, // No interface description string present. + + // + // Device Firmware Upgrade functional descriptor. + // + 9, // Length of this descriptor. + 0x21, // DFU Functional descriptor type + (DFU_ATTR_CAN_DOWNLOAD | // DFU attributes. + DFU_ATTR_CAN_UPLOAD | + DFU_ATTR_MANIFEST_TOLERANT), + USBShort(0xFFFF), // Detach timeout (set to maximum). + USBShort(DFU_TRANSFER_SIZE),// Transfer size 1KB. + USBShort(0x0110) // DFU Version 1.1 +}; + +//***************************************************************************** +// +// The USB device interrupt handler. +// +// This function is called to process USB interrupts when in device mode. +// This handler will branch the interrupt off to the appropriate application or +// stack handlers depending on the current status of the USB controller. +// +// \return None. +// +//***************************************************************************** +void +USB0DeviceIntHandler(void) +{ + uint32_t ui32TxStatus, ui32GenStatus; + + // + // Get the current full USB interrupt status. + // + ui32TxStatus = HWREGH(USB0_BASE + USB_O_TXIS); + ui32GenStatus = HWREGB(USB0_BASE + USB_O_IS); + + // + // Received a reset from the host. + // + if(ui32GenStatus & USB_IS_RESET) + { + USBDeviceEnumResetHandler(); + } + + // + // USB device was disconnected. + // + if(ui32GenStatus & USB_IS_DISCON) + { + HandleDisconnect(); + } + + // + // Handle end point 0 interrupts. + // + if(ui32TxStatus & USB_TXIE_EP0) + { + USBDeviceEnumHandler(); + } +} + +//***************************************************************************** +// +// A prototype for the function (in the startup code) for a predictable length +// delay. +// +//***************************************************************************** +extern void Delay(uint32_t ui32Count); + +//***************************************************************************** +// +// Send the current state or status structure back to the host. This function +// also acknowledges the request which causes us to send back this data. +// +//***************************************************************************** +void +SendDFUStatus(void) +{ + // + // Acknowledge the original request. + // + USBDevEndpoint0DataAck(false); + + // + // Copy the current state into the status structure we will return. + // + g_sDFUStatus.bState = (uint8_t)g_eDFUState; + g_sDFUStatus.bStatus = (uint8_t)g_eDFUStatus; + + // + // Send the status structure back to the host. + // + USBBLSendDataEP0((uint8_t *)&g_sDFUStatus, sizeof(tDFUGetStatusResponse)); +} + +//***************************************************************************** +// +// Send the next block of upload data back to the host assuming data remains +// to be sent. +// +// \param ui16Length is the requested amount of data. +// \param bAppendHeader is \b true to append a tDFUDownloadProgHeader at the +// start of the uploaded data or \b false if no header is required. +// +// Returns \b true if a full packet containing DFU_TRANSFER_SIZE bytes +// was sent and data remains to be sent following this transaction, or \b +// false if no more data remains to be sent following this transaction. +// +//***************************************************************************** +bool +SendUploadData(uint16_t ui16Length, bool bAppendHeader) +{ + uint16_t ui16ToSend; + uint32_t ui32Available; + + // + // Acknowledge the original request. + // + USBDevEndpoint0DataAck(false); + + // + // How much data is available to be sent? + // + ui32Available = (g_sNextUpload.ui32Length + + (bAppendHeader ? sizeof(tDFUDownloadProgHeader) : 0)); + + // + // How much data can we send? This is the smallest of the maximum transfer + // size, the requested length or the available data. + // + ui16ToSend = + (ui16Length > DFU_TRANSFER_SIZE) ? DFU_TRANSFER_SIZE : ui16Length; + ui16ToSend = + ((uint32_t)ui16ToSend > ui32Available) ? ui32Available : ui16ToSend; + + // + // If we have been asked to send a header, we need to copy some of the data + // into a buffer and send from there. If we don't do this, we run the risk + // of sending a long packet prematurely and ending the upload before it is + // complete. + // + if(bAppendHeader) + { + tDFUDownloadProgHeader *psHdr; + uint8_t *pui8From; + uint8_t *pui8To; + uint32_t ui32Loop; + + // + // We are appending a header so write the header information into a + // buffer then copy the first chunk of data from its original position + // into the same buffer. + // + psHdr = (tDFUDownloadProgHeader *)g_pui8DFUBuffer; + + // + // Build the header. + // + psHdr->ui8Command = DFU_CMD_PROG; + psHdr->ui8Reserved = 0; + psHdr->ui16StartAddr = ((uint32_t)(g_sNextUpload.pui8Start) / 1024); + psHdr->ui32Length = g_sNextUpload.ui32Length; + + // + // Copy the remainder of the first transfer's data from its original + // position. + // + pui8From = g_sNextUpload.pui8Start; + pui8To = (uint8_t *)(psHdr + 1); + for(ui32Loop = (ui16ToSend - sizeof(tDFUDownloadProgHeader)); ui32Loop; + ui32Loop--) + { + *pui8To++ = *pui8From++; + } + + // + // Send the data. + // + USBBLSendDataEP0((uint8_t *)psHdr, ui16ToSend); + + // + // Update our upload pointer and length. + // + g_sNextUpload.pui8Start += ui16ToSend - sizeof(tDFUDownloadProgHeader); + g_sNextUpload.ui32Length -= + ui16ToSend - sizeof(tDFUDownloadProgHeader); + } + else + { + // + // We are not sending a header so send the requested upload data back + // to the host directly from its original position. + // + USBBLSendDataEP0(g_sNextUpload.pui8Start, ui16ToSend); + + // + // Update our upload pointer and length. + // + g_sNextUpload.pui8Start += ui16ToSend; + g_sNextUpload.ui32Length -= ui16ToSend; + } + + // + // We return true if we sent a full packet (containing the maximum transfer + // size bytes) or false to indicate that a long packet was sent or no more + // data remains. + // + return(((ui16ToSend == DFU_TRANSFER_SIZE) && g_sNextUpload.ui32Length) ? + true : false); +} + +//***************************************************************************** +// +// Send the current state back to the host. +// +//***************************************************************************** +void +SendDFUState(void) +{ + // + // Acknowledge the original request. + // + USBDevEndpoint0DataAck(false); + + // + // Update the status structure with the current state. + // + g_sDFUStatus.bState = (uint8_t)g_eDFUState; + + // + // Send the state from the status structure back to the host. + // + USBBLSendDataEP0((uint8_t *)&g_sDFUStatus.bState, 1); +} + +//***************************************************************************** +// +//! Handle USB requests sent to the DFU device. +//! +//! \param psUSBRequest is a pointer to the USB request that the device has +//! been sent. +//! +//! This function is called to handle all non-standard requests received +//! by the device. This will include all the DFU endpoint 0 commands along +//! with the TIVA-specific request we use to query whether the device +//! supports our flavor of the DFU binary format. Incoming DFU requests are +//! processed by request handlers specific to the particular state of the DFU +//! connection. This state machine implementation is chosen to keep the +//! software as close as possible to the USB DFU class documentation. +//! +//! \return None. +// +//***************************************************************************** +void +HandleRequests(tUSBRequest *psUSBRequest) +{ + // + // This request is used by the host to determine whether the connected + // device supports the TIVA protocol extensions to DFU (our + // DFU_CMD_xxxx command headers passed alongside DNLOAD requests). We + // check the parameters and, if they are as expected, we respond with + // a 4 byte structure providing a marker and the protocol version + // number. + // + if(psUSBRequest->bRequest == USBD_DFU_REQUEST_TIVA) + { + // + // Check that the request parameters are all as expected. We are + // using the wValue value merely as a way of making it less likely + // that we respond to another vendor's device-specific request. + // + if((psUSBRequest->wLength == sizeof(tDFUQueryTIVAProtocol)) && + (psUSBRequest->wValue == REQUEST_TIVA_VALUE)) + { + // + // Acknowledge the original request. + // + USBDevEndpoint0DataAck(false); + + // + // Send the status structure back to the host. + // + USBBLSendDataEP0((uint8_t *)&g_sDFUProtocol, + sizeof(tDFUQueryTIVAProtocol)); + } + else + { + // + // The request parameters were not as expected so we assume + // that this is not our request and stall the endpoint to + // indicate an error. + // + USBBLStallEP0(); + } + + return; + } + + // + // Pass the request to the relevant handler depending upon our current + // state. If no handler is configured, we stall the endpoint since this + // implies that requests can't be handled in this state. + // + if(g_pfnRequestHandlers[g_eDFUState]) + { + // + // Dispatch the request to the relevant handler depending upon the + // current state. + // + (g_pfnRequestHandlers[g_eDFUState])(psUSBRequest); + } + else + { + USBBLStallEP0(); + } +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_IDLE. +// +//***************************************************************************** +void +HandleRequestIdle(tUSBRequest *psUSBRequest) +{ + switch(psUSBRequest->bRequest) + { + // + // This is a download request. We need to request the transaction + // payload unless this is a zero length request in which case we mark + // the error by stalling the endpoint. + // + case USBD_DFU_REQUEST_DNLOAD: + { + if(psUSBRequest->wLength) + { + USBBLRequestDataEP0(g_pui8DFUBuffer, psUSBRequest->wLength); + } + else + { + USBBLStallEP0(); + return; + } + break; + } + + // + // This is an upload request. We send back a block of data + // corresponding to the current upload pointer as held in + // g_sNextUpload. + // + case USBD_DFU_REQUEST_UPLOAD: + { + // + // If we have any upload data to send, send it. Make sure we append + // a header if required. + // + if(SendUploadData(psUSBRequest->wLength, + g_bSuppressUploadHeader ? false : + !g_bUploadBinary)) + { + // + // We sent a full (max packet size) frame to the host so + // transition to UPLOAD_IDLE state since we expect another + // upload request to continue the process. + // + g_eDFUState = STATE_UPLOAD_IDLE; + } + + // + // Clear the flag we use to suppress sending the DFU header. + // + g_bSuppressUploadHeader = false; + + return; + } + + // + // Return the current device status structure. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + SendDFUStatus(); + return; + } + + // + // Return the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + SendDFUState(); + return; + } + + // + // Ignore the ABORT request. This returns us to IDLE state but we're + // there already. + // + case USBD_DFU_REQUEST_ABORT: + { + break; + } + + // + // All other requests are illegal in this state so signal the error + // by stalling the endpoint. + // + case USBD_DFU_REQUEST_CLRSTATUS: + case USBD_DFU_REQUEST_DETACH: + default: + { + USBBLStallEP0(); + return; + } + } + + // + // If we drop out of the switch, we need to ACK the received request. + // + USBDevEndpoint0DataAck(false); +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_DNLOAD_SYNC or +// STATE_DNBUSY. +// +//***************************************************************************** +void +HandleRequestDnloadSync(tUSBRequest *psUSBRequest) +{ + // + // In this state, we have received a block of the download and are waiting + // for a USBD_DFU_REQUEST_GETSTATUS which will trigger a return + // to STATE_DNLOAD_IDLE assuming we have finished programming the block. + // If the last command we received was not DFU_CMD_PROG, we transition + // directly from this state back to STATE_IDLE once the last operation has + // completed since we need to be able to accept a new command. + // + switch(psUSBRequest->bRequest) + { + // + // The host is requesting the current device status. Return this and + // revert to STATE_IDLE. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + // + // Are we finished processing whatever the last flash-operation + // was? Note that we don't support DNLOAD_BUSY state in this + // implementation, we merely continue to report DNLOAD_SYNC state + // until we are finished with the command. + // + if(!g_ui32CommandFlags) + { + // + // If we are in the middle of a programming operation, + // transition back to DNLOAD_IDLE state to wait for the + // next block. If not, go back to idle since we expect a + // new command. + // + g_eDFUState = ((g_ui8LastCommand == DFU_CMD_PROG) ? + STATE_DNLOAD_IDLE : STATE_IDLE); + } + + // + // Send the latest status back to the host. + // + SendDFUStatus(); + + // + // Return here since we've already ACKed the request. + // + return; + } + + // + // The host is requesting the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + // + // Are we currently in DNLOAD_SYNC state? + // + if(g_eDFUState == STATE_DNLOAD_SYNC) + { + // + // Yes - send back the state. + // + SendDFUState(); + } + else + { + // + // In STATE_BUSY, we can't respond to any requests so stall + // the endpoint. + // + USBBLStallEP0(); + } + + // + // Return here since the incoming request has already been either + // ACKed or stalled by the processing above. + // + return; + } + + // + // Any other request is ignored and causes us to stall the control + // endpoint and remain in STATE_ERROR. + // + default: + { + USBBLStallEP0(); + return; + } + } +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_DNLOAD_IDLE. +// +//***************************************************************************** +void +HandleRequestDnloadIdle(tUSBRequest *psUSBRequest) +{ + switch(psUSBRequest->bRequest) + { + // + // This is a download request. We need to request the transaction + // payload unless this is a zero length request in which case we mark + // the error by stalling the endpoint. + // + case USBD_DFU_REQUEST_DNLOAD: + { + // + // Are we being passed data to program? + // + if(psUSBRequest->wLength) + { + // + // Yes - request the data. + // + USBBLRequestDataEP0(g_pui8DFUBuffer, psUSBRequest->wLength); + } + else + { + // + // No - this is the signal that a download operation is + // complete. Do we agree? + // + if(g_sNextDownload.ui32Length) + { + // + // We think there should still be some data to be received + // so mark this as an error. + // + g_eDFUState = STATE_ERROR; + g_eDFUStatus = STATUS_ERR_NOTDONE; + } + else + { + // + // We agree that the download has completed. Enter state + // STATE_MANIFEST_SYNC. + // + g_eDFUState = STATE_MANIFEST_SYNC; + } + } + break; + } + + // + // Return the current device status structure. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + SendDFUStatus(); + return; + } + + // + // Return the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + SendDFUState(); + return; + } + + // + // An ABORT request causes us to abort the current transfer and + // return the the idle state regardless of the state of the previous + // programming operation. + // + case USBD_DFU_REQUEST_ABORT: + { + // + // Default to downloading the main code image. + // + g_sNextDownload.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + g_sNextDownload.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); + g_eDFUState = STATE_IDLE; + break; + } + + // + // All other requests are illegal in this state so signal the error + // by stalling the endpoint. + // + case USBD_DFU_REQUEST_CLRSTATUS: + case USBD_DFU_REQUEST_DETACH: + case USBD_DFU_REQUEST_UPLOAD: + default: + { + USBBLStallEP0(); + return; + } + } + + // + // If we drop out of the switch, we need to ACK the received request. + // + USBDevEndpoint0DataAck(false); +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_MANIFEST_SYNC. +// +//***************************************************************************** +void +HandleRequestManifestSync(tUSBRequest *psUSBRequest) +{ + // + // In this state, we have received the last block of a download and are + // waiting for a USBD_DFU_REQUEST_GETSTATUS which will trigger a return + // to STATE_IDLE. + // + switch(psUSBRequest->bRequest) + { + // + // The host is requesting the current device status. Return this and + // revert to STATE_IDLE. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + g_eDFUState = STATE_IDLE; + SendDFUStatus(); + break; + } + + // + // The host is requesting the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + SendDFUState(); + break; + } + + // + // Any other request is ignored and causes us to stall the control + // endpoint and remain in STATE_MANIFEST_SYNC. + // + default: + { + USBBLStallEP0(); + break; + } + } +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_UPLOAD_IDLE. +// +//***************************************************************************** +void +HandleRequestUploadIdle(tUSBRequest *psUSBRequest) +{ + // + // In this state, we have already received the first upload request. What + // are we being asked to do now? + // + switch(psUSBRequest->bRequest) + { + // + // The host is requesting more upload data. + // + case USBD_DFU_REQUEST_UPLOAD: + { + // + // See if there is any more data to transfer and, if there is, + // send it back to the host. + // + if(!SendUploadData(psUSBRequest->wLength, false)) + { + // + // We sent less than a full packet of data so the transfer is + // complete. Revert to idle state and ensure that we reset + // our upload pointer and size to the default flash region. + // + g_eDFUState = STATE_IDLE; + g_sNextUpload.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + g_sNextUpload.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); + } + break; + } + + // + // The host is requesting the current device status. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + SendDFUStatus(); + break; + } + + // + // The host is requesting the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + SendDFUState(); + break; + } + + // + // The host is requesting that we abort the current upload. + // + case USBD_DFU_REQUEST_ABORT: + { + // + // Default to sending the main application image for the next + // upload. + // + g_sNextUpload.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + g_sNextUpload.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); + g_eDFUState = STATE_IDLE; + break; + } + + // + // Any other request is ignored and causes us to stall the control + // endpoint and remain in STATE_ERROR. + // + default: + { + USBBLStallEP0(); + break; + } + } +} + +//***************************************************************************** +// +// Handle all incoming DFU requests while in state STATE_ERROR. +// +//***************************************************************************** +void +HandleRequestError(tUSBRequest *psUSBRequest) +{ + // + // In this state, we respond to state and status requests and also to + // USBD_DFU_REQUEST_CLRSTATUS which clears the previous error condition. + // + switch(psUSBRequest->bRequest) + { + // + // The host is requesting the current device status. + // + case USBD_DFU_REQUEST_GETSTATUS: + { + SendDFUStatus(); + break; + } + + // + // The host is requesting the current device state. + // + case USBD_DFU_REQUEST_GETSTATE: + { + SendDFUState(); + break; + } + + // + // The host is asking us to clear our previous error condition and + // revert to idle state in preparation to receive new commands. + // + case USBD_DFU_REQUEST_CLRSTATUS: + { + g_eDFUState = STATE_IDLE; + g_eDFUStatus = STATUS_OK; + USBDevEndpoint0DataAck(false); + break; + } + + // + // Any other request is ignored and causes us to stall the control + // endpoint and remain in STATE_ERROR. + // + default: + { + USBBLStallEP0(); + break; + } + } +} + +//***************************************************************************** +// +// Handle cases where the host sets a new USB configuration. +// +//***************************************************************************** +void +HandleConfigChange(uint32_t ui32Info) +{ + // + // Revert to idle state. + // + g_eDFUState = STATE_IDLE; + g_eDFUStatus = STATUS_OK; +} + +//***************************************************************************** +// +// Setting the device address indicates that we are now connected to the host +// and can expect some DFU communication so we use this opportunity to clean +// out our state just in case we were not idle last time the host disconnected. +// +//***************************************************************************** +void +HandleSetAddress(void) +{ + g_eDFUState = STATE_IDLE; + g_eDFUStatus = STATUS_OK; + g_bAddressSet = true; + + // + // Default the download address to the app start address and valid length + // to the whole of the programmable flash area. + // + g_sNextDownload.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + g_sNextDownload.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); + + // + // Default the upload address to the app start address and valid length + // to the whole of the programmable flash area. + // + g_sNextUpload.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + g_sNextUpload.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); +} + +//***************************************************************************** +// +// Check that a range of addresses passed is within the region of flash that +// the boot loader is allowed to access. +// +// Returns true if the address range is accessible or false otherwise. +// +//***************************************************************************** +bool +FlashRangeCheck(uint32_t ui32Start, uint32_t ui32Length) +{ +#ifdef ENABLE_BL_UPDATE + if((ui32Length <= + (g_sDFUDeviceInfo.ui32FlashTop - g_sDFUDeviceInfo.ui32AppStartAddr)) && + ((ui32Start + ui32Length) <= g_sDFUDeviceInfo.ui32FlashTop)) +#else + if((ui32Start >= g_sDFUDeviceInfo.ui32AppStartAddr) && + (ui32Length <= + (g_sDFUDeviceInfo.ui32FlashTop - g_sDFUDeviceInfo.ui32AppStartAddr)) && + ((ui32Start + ui32Length) <= g_sDFUDeviceInfo.ui32FlashTop)) +#endif + { + // + // The block passed lies wholly within the flash address range of + // this device. + // + return(true); + } + else + { + // + // We were passed an address that is out of range so set the + // appropriate status code. + // + g_eDFUStatus = STATUS_ERR_ADDRESS; + return(false); + } +} + +//***************************************************************************** +// +//! Process TIVA-specific commands passed via DFU download requests. +//! +//! \param psCmd is a pointer to the first byte of the \b DFU_DNLOAD payload +//! that is expected to hold a command. +//! \param ui32Size is the number of bytes of data pointed to by \e psCmd. +//! This function is called when a DFU download command is received while in +//! \b STATE_IDLE. New downloads are assumed to contain a prefix structure +//! containing one of several TIVA-specific commands and this function +//! is responsible for parsing the download data and processing whichever +//! command is contained within it. +//! +//! \return Returns \b true on success or \b false on failure. +// +//***************************************************************************** +bool +ProcessDFUDnloadCommand(tDFUDownloadHeader *psCmd, uint32_t ui32Size) +{ + // + // Make sure we got enough data to contain a valid command header. + // + if(ui32Size < sizeof(tDFUDownloadHeader)) + { + return(false); + } + + // + // Remember the command that we have been passed since we will need thi + // to determine which state to transition to on exit from STATE_DNLOAD_SYNC. + // + g_ui8LastCommand = psCmd->ui8Command; + + // + // Which command have we been passed? + // + switch(psCmd->ui8Command) + { + // + // We are being asked to start a programming operation. + // + case DFU_CMD_PROG: + { + tDFUDownloadProgHeader *psHdr; + + // + // Extract the address and size from the command header. + // + psHdr = (tDFUDownloadProgHeader *)psCmd; + + // + // Is the passed address range valid? + // + if(BL_FLASH_AD_CHECK_FN_HOOK(psHdr->ui16StartAddr * 1024, + psHdr->ui32Length)) + { + // + // Yes - remember the range passed so that we will write the + // passed data to the correct place. + // + g_sNextDownload.pui8Start = + (uint8_t *)(psHdr->ui16StartAddr * 1024); + g_sNextDownload.ui32Length = psHdr->ui32Length; + + // + // If we have been provided with a progress reporting hook + // function, remember the total length of the image so that + // we can report this later. + // +#ifdef BL_PROGRESS_FN_HOOK + g_ui32ImageSize = psHdr->ui32Length; +#endif + + // + // Also set the upload address and size to match this download + // so that, by default, the host will get back what it just + // wrote if it performs an upload without an intermediate + // DFU_CMD_READ to set the address and size. + // + g_sNextUpload.pui8Start = + (uint8_t *)(psHdr->ui16StartAddr * 1024); + g_sNextUpload.ui32Length = psHdr->ui32Length; + + // + // Also remember that we have data in this packet to write. + // + g_pui8DFUWrite = (uint8_t *)(psHdr + 1); + g_ui16DFUBufferUsed = ui32Size - sizeof(tDFUDownloadHeader); + + // + // If a start signal hook function has been provided, call it + // here since we are about to start a new download. + // +#ifdef BL_START_FN_HOOK + BL_START_FN_HOOK(); +#endif + + // + // If FLASH_CODE_PROTECTION is defined in bl_config.h we + // erase the whole application area at this point before we + // start to flash the new image. + // +#ifdef FLASH_CODE_PROTECTION + g_sErase.pui8Start = + (uint8_t *)g_sDFUDeviceInfo.ui32AppStartAddr; + + g_sErase.ui32Length = (g_sDFUDeviceInfo.ui32FlashTop - + g_sDFUDeviceInfo.ui32AppStartAddr); + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_ERASE) = 1; +#endif + + // + // Tell the main thread to write the data we just received it. + // + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_WRITE) = 1; + } + else + { + // + // The flash range was invalid so switch to error state. + // + return(false); + } + break; + } + + // + // We are being passed the position and size of a block of flash to + // return in a following upload operation. + // + case DFU_CMD_READ: + { + tDFUDownloadReadCheckHeader *psHdr; + + // + // Extract the address and size from the command header. + // + psHdr = (tDFUDownloadReadCheckHeader *)psCmd; + + // + // Is the passed address range valid? + // + if(FlashRangeCheck(psHdr->ui16StartAddr * 1024, psHdr->ui32Length)) + { + // + // Yes - remember the range passed so that we will return + // this block of flash on the next upload request. + // + g_sNextUpload.pui8Start = + (uint8_t *)(psHdr->ui16StartAddr * 1024); + g_sNextUpload.ui32Length = psHdr->ui32Length; + } + else + { + // + // The flash range was invalid so switch to error state. + // + return(false); + } + break; + } + + // + // We are being passed the position and size of a block of flash which + // we will check to ensure that it is erased. + // + case DFU_CMD_CHECK: + { + tDFUDownloadReadCheckHeader *psHdr; + uint32_t *pui32Check; + uint32_t ui32Loop; + + // + // Extract the address and size from the command header. + // + psHdr = (tDFUDownloadReadCheckHeader *)psCmd; + + // + // Make sure the range we have been passed is within the area of + // flash that we are allowed to look at. + // + if(FlashRangeCheck(psHdr->ui16StartAddr * 1024, psHdr->ui32Length)) + { + // + // The range is valid so perform the check here. + // + pui32Check = (uint32_t *)(psHdr->ui16StartAddr * 1024); + + // + // Check each word in the range to ensure that it is erased. If + // not, set the error status and return. + // + for(ui32Loop = 0; ui32Loop < (psHdr->ui32Length / 4); + ui32Loop++) + { + if(*pui32Check != 0xFFFFFFFF) + { + g_eDFUStatus = STATUS_ERR_CHECK_ERASED; + return(false); + } + pui32Check++; + } + + // + // If we get here, the check passed so set the status to + // indicate this. + // + g_eDFUStatus = STATUS_OK; + } + else + { + // + // The flash range was invalid so switch to error state. + // + return(false); + } + break; + } + + // + // We are being asked to erase a block of flash. + // + case DFU_CMD_ERASE: + { + tDFUDownloadEraseHeader *psHdr; + + // + // Extract the address and size from the command header. + // + psHdr = (tDFUDownloadEraseHeader *)psCmd; + + // + // Make sure the range we have been passed is within the area of + // flash that we are allowed to look at. + // + if(FlashRangeCheck((uint32_t)psHdr->ui16StartAddr * 1024, + ((uint32_t)psHdr->ui16NumBlocks * + DFU_REPORTED_PAGE_SIZE ))) + { + // + // The range is valid so tell the main loop to erase the + // block. + // + g_sErase.pui8Start = (uint8_t *) + ((uint32_t)psHdr->ui16StartAddr * 1024); + g_sErase.ui32Length = ((uint32_t)psHdr->ui16NumBlocks * + DFU_REPORTED_PAGE_SIZE); + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_ERASE) = 1; + } + else + { + // + // The flash range was invalid so switch to error state. + // + return(false); + } + break; + } + + // + // We are being asked to send back device information on the next + // upload request. + // + case DFU_CMD_INFO: + { + // + // Register that we need to send the device info structure on the + // next upload request. + // + g_sNextUpload.pui8Start = (uint8_t *)&g_sDFUDeviceInfo; + g_sNextUpload.ui32Length = sizeof(tDFUDeviceInfo); + + // + // Make sure we don't append the DFU_CMD_PROG header when we send + // back the data. + // + g_bSuppressUploadHeader = true; + break; + } + + // + // We are being asked to set the format of uploaded images. + // + case DFU_CMD_BIN: + { + tDFUDownloadBinHeader *psHdr; + + // + // Extract the required format the command header. + // + psHdr = (tDFUDownloadBinHeader *)psCmd; + + // + // Set the global format appropriately. + // + g_bUploadBinary = psHdr->bBinary ? true : false; + break; + } + + // + // We are being asked to prepare to reset the board and, as a result, + // run the main application image. + // + case DFU_CMD_RESET: + { + // + // Tell the main thread that it's time to go bye-bye... + // + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_RESET) = 1; + + break; + } + + // + // We have been passed an unrecognized command identifier so report an + // error. + // + default: + { + g_eDFUStatus = STATUS_ERR_VENDOR; + return(false); + } + } + + return(true); +} + +//***************************************************************************** +// +// This callback function is called when data is received for the DATA phase +// of an EP0 OUT transaction. This data will either be a block of download +// data (if we are in STATE_DNLOAD_IDLE) or a new command (if we are in +// STATE_IDLE). +// +//***************************************************************************** +void +HandleEP0Data(uint32_t ui32Size) +{ + bool bRetcode; + + if(g_eDFUState == STATE_IDLE) + { + // + // This must be a new DFU download command header so parse it and + // determine what to do next. + // + bRetcode = + ProcessDFUDnloadCommand((tDFUDownloadHeader *)g_pui8DFUBuffer, + ui32Size); + + // + // Did we receive a recognized and valid command? + // + if(!bRetcode) + { + // + // No - set the error state. The status is set within the + // ProcessDFUDnloadCommand() function. + // + g_eDFUState = STATE_ERROR; + return; + } + } + else + { + // + // If we are not in STATE_IDLE, this must be a block of data for an + // ongoing download so signal the main thread to write it to flash. + // + g_ui16DFUBufferUsed = (uint16_t)ui32Size; + g_pui8DFUWrite = g_pui8DFUBuffer; + + // + // Tell the main thread to write the new data. + // + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_WRITE) = 1; + } + + // + // Move to STATE_DNLOAD_SYNC since we now expect USBD_DFU_REQUEST_GETSTATUS + // before the next USBD_DFU_REQUEST_DNLOAD. + // + g_eDFUState = STATE_DNLOAD_SYNC; +} + +//***************************************************************************** +// +// Handle bus resets +// +// This function is called if the USB controller detects a reset condition on +// the bus. If we are not in the process of downloading a new image, we use +// this as a signal to reboot and run the main application image. +// +//***************************************************************************** +void +HandleReset(void) +{ + // + // Are we currently in the middle of a download operation? + // + if((g_eDFUState != STATE_DNLOAD_IDLE) && + (g_eDFUState != STATE_DNLOAD_SYNC) && (g_eDFUState != STATE_IDLE)) + { + // + // No - tell the main thread that it should reboot the system assuming + // that we are already configured. If we don't check that we are + // already configured, this will cause a reset during initial + // enumeration and that wouldn't be very helpful. + // + if(g_bAddressSet) + { + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_RESET) = 1; + } + } +} + +//***************************************************************************** +// +// Handle cases where the USB host disconnects. +// +//***************************************************************************** +void +HandleDisconnect(void) +{ + // + // For error resilience, it may be desireable to note if the host + // disconnects and, if partway through a main image download, clear the + // first block of the flash to ensure that the image is not considered + // valid on the next boot. For now, however, we merely wait for the host + // to connect again, remaining in DFU mode. + // + + // + // Remember that we are waiting for enumeration. + // + g_bAddressSet = false; +} + +//***************************************************************************** +// +// Erase a single block of flash +// +// This function erases a single, 1KB block of flash, returning once the +// operation has completed. +// +// \return None. +// +//***************************************************************************** +static void +EraseFlashBlock(uint32_t ui32Addr) +{ + BL_FLASH_ERASE_FN_HOOK(ui32Addr); +} + +//***************************************************************************** +// +//! This is the main routine for handling updating over USB. +//! +//! This function forms the main loop of the USB DFU updater. It polls for +//! commands sent from the USB request handlers and is responsible for +//! erasing flash blocks, programming data into erased blocks and resetting +//! the device. +//! +//! \return None. +// +//***************************************************************************** +void +UpdaterUSB(void) +{ + uint32_t ui32Idx, ui32Start, ui32Temp; + uint16_t ui16Used; +#ifndef FLASH_CODE_PROTECTION + uint32_t ui32End; +#endif + + // + // Loop forever waiting for the USB interrupt handlers to tell us to do + // something. + // + while(1) + { + while(g_ui32CommandFlags == 0) + { + // + // Wait for something to do. + // + } + + // + // Are we being asked to perform a system reset? + // + if(HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_RESET)) + { + // + // Time to go bye-bye... This will cause the microcontroller + // to reset; no further code will be executed. + // + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; + + // + // The microcontroller should have reset, so this should never be + // reached. Just in case, loop forever. + // + while(1) + { + } + } + + // + // Are we being asked to erase a range of blocks in flash? + // + if(HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_ERASE)) + { + // + // Loop through the pages in the block of flash we have been asked + // to erase and clear each one. + // + ui32Temp = g_sErase.ui32Length; + for(ui32Idx = (uint32_t)g_sErase.pui8Start; + ui32Idx < (uint32_t)(g_sErase.pui8Start + ui32Temp); + ui32Idx += FLASH_PAGE_SIZE) + { + EraseFlashBlock(ui32Idx); + } + + // + // Clear the command flag to indicate that we are done. + // + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_ERASE) = 0; + } + + // + // Are we being asked to program a block of flash? + // + if(HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_WRITE)) + { + // + // Decrypt the data if required. + // +#ifdef BL_DECRYPT_FN_HOOK + BL_DECRYPT_FN_HOOK(g_pui8DFUWrite, g_ui16DFUBufferUsed); +#endif + + // + // Where will the new block be written? + // + ui32Start = (uint32_t)(g_sNextDownload.pui8Start); + +#ifndef FLASH_CODE_PROTECTION + // + // What is the address of the last byte we will write in this + // block of data? We copy g_ui16DFUBufferUsed to prevent warnings + // about "undefined order of volatile accesses" from some + // compilers. + // + ui16Used = g_ui16DFUBufferUsed; + + ui32End = (uint32_t)g_sNextDownload.pui8Start + ui16Used - 1; + + // + // Are we writing data at the start of a new flash block? If so, + // we need to erase the content of the block first. + // + if((ui32Start & (FLASH_PAGE_SIZE - 1)) == 0) + { + // + // We are writing to the start of a block so erase it. + // + EraseFlashBlock(ui32Start & ~(FLASH_PAGE_SIZE - 1)); + } + else + { + // + // Will this block of data straddle two flash blocks? If so, + // we need to erase the following block. + // + if((ui32Start & ~(FLASH_PAGE_SIZE - 1)) != + (ui32End & ~(FLASH_PAGE_SIZE - 1))) + { + EraseFlashBlock(ui32End & ~(FLASH_PAGE_SIZE - 1)); + } + } +#endif + + // + // Write the new block of data to the flash + // + BL_FLASH_PROGRAM_FN_HOOK(ui32Start, g_pui8DFUWrite, ui16Used); + + // + // Update our position and remaining size. + // + g_sNextDownload.pui8Start += ui16Used; + g_sNextDownload.ui32Length -= ui16Used; + + // + // Clear the command flag to indicate that we are done. + // + HWREGBITW(&g_ui32CommandFlags, CMD_FLAG_WRITE) = 0; + + // + // If a progress hook function has been provided, call + // it here. + // +#ifdef BL_PROGRESS_FN_HOOK + BL_PROGRESS_FN_HOOK(g_ui32ImageSize - g_sNextDownload.ui32Length, + g_ui32ImageSize); +#endif + + // + // If we just finished the download and an end signal hook function + // has been provided, call it too. + // +#ifdef BL_END_FN_HOOK + if(g_sNextDownload.ui32Length == 0) + { + BL_END_FN_HOOK(); + } +#endif + } + } +} + +//***************************************************************************** +// +//! Configure the USB controller and place the DFU device on the bus. +//! +//! This function configures the USB controller for DFU device operation, +//! initializes the state machines required to control the firmware update and +//! places the device on the bus in preparation for requests from the host. It +//! is assumed that the main system clock has been configured at this point. +//! +//! \return None. +// +//***************************************************************************** +void +ConfigureUSBInterface(void) +{ + uint32_t ui32FlashSize; + + // + // Initialize our device information structure. + // + ui32FlashSize = BL_FLASH_SIZE_FN_HOOK(); + + g_sDFUDeviceInfo.ui16FlashBlockSize = DFU_REPORTED_PAGE_SIZE; + g_sDFUDeviceInfo.ui16NumFlashBlocks = + ui32FlashSize / DFU_REPORTED_PAGE_SIZE; + g_sDFUDeviceInfo.ui32ClassInfo = HWREG(SYSCTL_DID0); + g_sDFUDeviceInfo.ui32PartInfo = HWREG(SYSCTL_DID1); + g_sDFUDeviceInfo.ui32AppStartAddr = APP_START_ADDRESS; +#ifdef FLASH_RSVD_SPACE + g_sDFUDeviceInfo.ui32FlashTop = ui32FlashSize - FLASH_RSVD_SPACE; +#else + g_sDFUDeviceInfo.ui32FlashTop = ui32FlashSize; +#endif + + // + // Publish our DFU device descriptors and place the device on the bus. + // + USBBLInit(); +} + +#if (defined USB_HAS_MUX) || (defined DOXYGEN) +//***************************************************************************** +// +//! Configures and set the mux selecting USB device-mode operation. +//! +//! On target boards which use a multiplexer to switch between USB host and +//! device operation, this function is used to configure the relevant GPIO +//! pin and drive it such that the mux selects USB device-mode operation. +//! If \b USB_HAS_MUX is not defined in bl_config.h, this function is compiled +//! out. +//! +//! \return None. +// +//***************************************************************************** +static void +SetUSBMux(void) +{ + // + // Enable the GPIO peripheral that contains the mux control pin. + // + HWREG(SYSCTL_RCGCGPIO) |= USB_MUX_PERIPH; + + // + // Delay a very short period before we access the newly-enabled peripheral. + // + Delay(1); + + // + // Make the pin be an output. + // + HWREG(USB_MUX_PORT + GPIO_O_DIR) |= (1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_AFSEL) &= ~(1 << USB_MUX_PIN); + + // + // Set the output drive strength to 2mA. + // + HWREG(USB_MUX_PORT + GPIO_O_DR2R) |= (1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_DR4R) &= ~(1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_DR8R) &= ~(1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_SLR) &= ~(1 << USB_MUX_PIN); + + // + // Set the pin type to a normal, GPIO output. + // + HWREG(USB_MUX_PORT + GPIO_O_ODR) &= ~(1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_PUR) &= ~(1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_PDR) &= ~(1 << USB_MUX_PIN); + HWREG(USB_MUX_PORT + GPIO_O_DEN) |= (1 << USB_MUX_PIN); + + // + // Clear this pin's bit in the analog mode select register. + // + HWREG(USB_MUX_PORT + GPIO_O_AMSEL) &= ~(1 << USB_MUX_PIN); + + // + // Write the pin to the appropriate level to select USB device mode. + // + HWREG(USB_MUX_PORT + (GPIO_O_DATA + ((1 << USB_MUX_PIN) << 2))) = + (USB_MUX_DEVICE ? (1 << USB_MUX_PIN) : 0); +} +#endif + +//***************************************************************************** +// +//! Generic configuration is handled in this function. +//! +//! This function is called by the start up code to perform any configuration +//! necessary before calling the update routine. It is responsible for setting +//! the system clock to the expected rate and setting flash programming +//! parameters prior to calling ConfigureUSBInterface() to set up the USB +//! hardware and place the DFU device on the bus. +//! +//! \return None. +// +//***************************************************************************** +void +ConfigureUSB(void) +{ +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. Check for whether the Oscillator range + // has to be set and wait states need to be updated + // + if(CRYSTAL_FREQ >= 10000000) + { + HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG); + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + else + { + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + + // + // Wait for the Oscillator to Stabilize + // + Delay(524288); + + if(CRYSTAL_FREQ > 16000000) + { + HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_FWS_S) | + SYSCTL_MEMTIM0_EBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_EWS_S) | + SYSCTL_MEMTIM0_MB1); + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_MEMTIMU | + SYSCTL_RSCLKCFG_PLLSRC_MOSC | + SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } + else + { + HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_PLLSRC_MOSC | + SYSCTL_RSCLKCFG_OSCSRC_MOSC); + } + + // + // Program the PLLFREQ0 and PLLFREQ1 registers for 480MHz + // VCO Clock from the PLL and output clock of 240MHz using the Q divider. + // Enable the PLL Power Up. + // + HWREG(SYSCTL_PLLFREQ1) = (1 << SYSCTL_PLLFREQ1_Q_S | + 4 << SYSCTL_PLLFREQ1_N_S); + HWREG(SYSCTL_PLLFREQ0) = (SYSCTL_PLLFREQ0_PLLPWR | + (96 << SYSCTL_PLLFREQ0_MINT_S)); + + // + // Wait for the PLL to Lock + // + while((HWREG(SYSCTL_PLLSTAT) & SYSCTL_PLLSTAT_LOCK) != SYSCTL_PLLSTAT_LOCK) + { + } + + // + // Program the MEMTIM0 for 120MHz System Clock + // + HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_3_5 | + (5 << SYSCTL_MEMTIM0_FWS_S) | + SYSCTL_MEMTIM0_EBCHT_3_5 | + (5 << SYSCTL_MEMTIM0_EWS_S) | + SYSCTL_MEMTIM0_MB1); + + // + // Program the RSCLKCFG to switch to the PLL + // with System Clock as 120MHz + // + HWREG(SYSCTL_RSCLKCFG) |= (SYSCTL_RSCLKCFG_MEMTIMU | + SYSCTL_RSCLKCFG_USEPLL | + 0x1); +#else + // + // Enable the main oscillator. + // + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS); + + // + // Delay while the main oscillator starts up. + // + Delay(524288); + + // + // Set the crystal frequency, switch to the main oscillator, and enable the + // PLL. + // + HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & + ~(SYSCTL_RCC_PWRDN | SYSCTL_RCC_XTAL_M | + SYSCTL_RCC_OSCSRC_M)) | + XTAL_VALUE | SYSCTL_RCC_OSCSRC_MAIN); + + // + // Delay while the PLL locks. + // + Delay(524288); + + // + // Disable the PLL bypass so that the part is clocked from the PLL, and set + // sysdiv to 8. This yields a system clock of 25MHz. + // + HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & ~(SYSCTL_RCC_BYPASS | + SYSCTL_RCC_SYSDIV_M)) | + ((7 - 1) << SYSCTL_RCC_SYSDIV_S) | + SYSCTL_RCC_USESYSDIV); +#endif + + // + // If the target device has a mux to allow selection of USB host or + // device mode, make sure this is set to device mode. + // +#ifdef USB_HAS_MUX + SetUSBMux(); +#endif + + // + // Configure the USB interface and put the device on the bus. + // + ConfigureUSBInterface(); +} + +//***************************************************************************** +// +//! This is the application entry point to the USB updater. +//! +//! This function should only be entered from a running application and not +//! when running the boot loader with no application present. If the +//! calling application supports any USB device function, it must remove +//! itself from the USB bus prior to calling this function. This function +//! assumes that the calling application has already configured the system +//! clock to run from the PLL. +//! +//! \return None. +// +//***************************************************************************** +void +AppUpdaterUSB(void) +{ +#if defined(TARGET_IS_TM4C129_RA0) || \ + defined(TARGET_IS_TM4C129_RA1) || \ + defined(TARGET_IS_TM4C129_RA2) + // + // Since the crystal frequency was specified, enable the main oscillator + // and clock the processor from it. Check for whether the Oscillator range + // has to be set and wait states need to be updated + // + if(CRYSTAL_FREQ >= 10000000) + { + HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG); + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + else + { + HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | + SYSCTL_MOSCCTL_NOXTAL); + } + + // + // Wait for the Oscillator to Stabilize + // + Delay(524288); + + if(CRYSTAL_FREQ > 16000000) + { + HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_FWS_S) | + SYSCTL_MEMTIM0_EBCHT_1_5 | + (1 << SYSCTL_MEMTIM0_EWS_S) | + SYSCTL_MEMTIM0_MB