Repository: danielnilsson9/bbs-fw Branch: master Commit: 10cadba77456 Files: 145 Total size: 1.3 MB Directory structure: gitextract_0i0vlkpl/ ├── .editorconfig ├── .github/ │ └── FUNDING.yml ├── LICENSE ├── README.md ├── drawings/ │ └── pcb/ │ ├── bbshd.sch │ └── eagle.epf └── src/ ├── firmware/ │ ├── .gitignore │ ├── Makefile │ ├── adc.h │ ├── app.c │ ├── app.h │ ├── battery.c │ ├── battery.h │ ├── bbs-fw.sln │ ├── bbs-fw.vcxproj │ ├── bbs-fw.vcxproj.filters │ ├── bbsx/ │ │ ├── adc.c │ │ ├── cpu.h │ │ ├── eeprom.c │ │ ├── interrupt.h │ │ ├── lights.c │ │ ├── motor.c │ │ ├── pins.h │ │ ├── sensors.c │ │ ├── stc15.h │ │ ├── system.c │ │ ├── timers.c │ │ ├── timers.h │ │ ├── uart.c │ │ ├── uart_motor.h │ │ └── watchdog.c │ ├── cfgstore.c │ ├── cfgstore.h │ ├── clean.bat │ ├── eeprom.h │ ├── eventlog.c │ ├── eventlog.h │ ├── extcom.c │ ├── extcom.h │ ├── fwconfig.h │ ├── intellisense.h │ ├── interrupt.h │ ├── lights.h │ ├── main.c │ ├── motor.h │ ├── sensors.h │ ├── system.h │ ├── throttle.c │ ├── throttle.h │ ├── timers.h │ ├── tohex.bat │ ├── tsdz2/ │ │ ├── adc.c │ │ ├── cpu.h │ │ ├── eeprom.c │ │ ├── interrupt.h │ │ ├── lights.c │ │ ├── motor.c │ │ ├── pins.h │ │ ├── sensors.c │ │ ├── stm8.h │ │ ├── stm8s/ │ │ │ ├── stm8s.h │ │ │ ├── stm8s_adc1.h │ │ │ ├── stm8s_adc2.h │ │ │ ├── stm8s_awu.h │ │ │ ├── stm8s_beep.h │ │ │ ├── stm8s_can.h │ │ │ ├── stm8s_clk.h │ │ │ ├── stm8s_exti.h │ │ │ ├── stm8s_flash.h │ │ │ ├── stm8s_gpio.h │ │ │ ├── stm8s_i2c.h │ │ │ ├── stm8s_itc.h │ │ │ ├── stm8s_iwdg.h │ │ │ ├── stm8s_rst.h │ │ │ ├── stm8s_spi.h │ │ │ ├── stm8s_tim1.h │ │ │ ├── stm8s_tim2.h │ │ │ ├── stm8s_tim3.h │ │ │ ├── stm8s_tim4.h │ │ │ ├── stm8s_tim5.h │ │ │ ├── stm8s_tim6.h │ │ │ ├── stm8s_uart1.h │ │ │ ├── stm8s_uart2.h │ │ │ ├── stm8s_uart3.h │ │ │ ├── stm8s_uart4.h │ │ │ └── stm8s_wwdg.h │ │ ├── system.c │ │ ├── timers.c │ │ ├── timers.h │ │ ├── torquesensor.c │ │ ├── uart.c │ │ └── watchdog.c │ ├── uart.h │ ├── util.h │ ├── version.h │ └── watchdog.h ├── logger/ │ ├── .gitignore │ ├── .vscode/ │ │ └── extensions.json │ ├── include/ │ │ └── ComProxy.h │ ├── platformio.ini │ └── src/ │ ├── ComProxy.cpp │ └── Main.cpp └── tool/ ├── .gitignore ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Model/ │ ├── BbsfwConnection.cs │ ├── CompletionQueue.cs │ ├── Configuration.cs │ └── EventLogEntry.cs ├── Properties/ │ ├── Settings.Designer.cs │ └── Settings.settings ├── View/ │ ├── AssistLevelCruiseView.xaml │ ├── AssistLevelCruiseView.xaml.cs │ ├── AssistLevelPasView.xaml │ ├── AssistLevelPasView.xaml.cs │ ├── AssistLevelThrottleView.xaml │ ├── AssistLevelThrottleView.xaml.cs │ ├── AssistLevelsView.xaml │ ├── AssistLevelsView.xaml.cs │ ├── CalibrationView.xaml │ ├── CalibrationView.xaml.cs │ ├── ConnectionView.xaml │ ├── ConnectionView.xaml.cs │ ├── Converter/ │ │ └── TimestampConverter.cs │ ├── EventLogView.xaml │ ├── EventLogView.xaml.cs │ ├── Extension/ │ │ └── DataGridExtension.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── SystemView.xaml │ └── SystemView.xaml.cs ├── ViewModel/ │ ├── AssistLevelViewModel.cs │ ├── AssistLevelsViewModel.cs │ ├── Base/ │ │ ├── DelegateCommand.cs │ │ └── ObservableObject.cs │ ├── CalibrationViewModel.cs │ ├── ConfigurationViewModel.cs │ ├── ConnectionViewModel.cs │ ├── EventLogViewModel.cs │ ├── MainViewModel.cs │ ├── SystemViewModel.cs │ └── ValueItemViewModel.cs ├── bbs-fw-tool.csproj └── bbs-fw-tool.sln ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] end_of_line = crlf insert_final_newline = true charset = utf-8 indent_style = tab indent_size = 4 trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false ================================================ FILE: .github/FUNDING.yml ================================================ custom: https://www.paypal.com/donate/?business=LVAYFCMQYN8F4&no_recurring=0&item_name=BBSHD-FW¤cy_code=USD ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: README.md ================================================ # BBSHD/BBS02/TSDZ2 Open Source Firmware ![GitHub all releases](https://img.shields.io/github/downloads/danielnilsson9/bbs-fw/total?style=for-the-badge) ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/danielnilsson9/bbs-fw?include_prereleases&style=for-the-badge) ![GitHub](https://img.shields.io/github/license/danielnilsson9/bbs-fw?style=for-the-badge) This firmware is intended to replace the original Bafang firmware on the BBSHD/BBS02 motor controller. Almost all functionality of original firmware has been implemented and additional features have been added. This firmware is compatible with all displays that works with the original Bafang firmware. A custom configuration tool is provided since BafangConfigTool is not compatible due to a different set of supported parameters. The firmware is also compatible with the TongSheng TSDZ2 controller but requires a custom made cable in order to interface with Bafang compatible displays. ⚠️ Warning: The firmware should NOT be flashed or configured while the eBike battery is charging! **Download** https://github.com/danielnilsson9/bbshd-fw/releases **Install** https://github.com/danielnilsson9/bbs-fw/wiki/Flash-Firmware-(BBS02-&-BBSHD) **Configure** https://github.com/danielnilsson9/bbshd-fw/wiki/Configuration-Tool If you find this project useful, consider sending a small [donation](https://www.paypal.com/donate/?business=LVAYFCMQYN8F4&no_recurring=0&item_name=BBSHD-FW¤cy_code=USD) to fund further development. ## Known Issues * ⚠️ Unstable on BBS02 controllers! ## Highlights * ✅ A bit more power without hardware modifications! (max 33A). * ✅ No upper voltage limit in software, can by default run up to 63V (maximum rating of components). * ✅ Support lower voltage cutoff for use with e.g. 36V battery. * ✅ Smooth Throttle/PAS override. * ✅ Optional separate set of street legal & offroad assist levels which can be toggled by a key combination. * ✅ Support setting road speed limit per assist level. * ✅ Support setting cadence limit per assist level. * ✅ Support cruise assist levels (i.e. motor power without pedal or throttle input). * ✅ Thermal limiting gradual ramp down. * ✅ Low voltage gradual ramp down. * ✅ Voltage calibration for accurate LVC and low voltage ramp down. * ✅ Display motor/controller temperature on standard display. * ✅ Use of speed sensor is optional. ![Config Tool](https://github.com/user-attachments/assets/1534c303-b25f-4fa4-8b37-5b74ade4a800) ## Supported Hardware ### BBSHD Revision | MCU | Released | Comment -------- | ------------ | ----------- | -------------------- V1.4 | STC15W4K56S4 | ~2017 | V1.3 printed on PCB, sticker with 1.4. V1.5 | IAP15W4K61S4 | ~2019 | V1.4 printed on PCB, sticker with 1.5. ### BBS02B There are compatibility issues reported, this firmware is suspected to be incompatible with older BBS02 controllers. If you have a newer BBS02B you are probably fine, if you have an older controller it might not be a good idea to flash this firmware. Revision | MCU | Released | Comment -------- | ------------ | ----------- | -------------------- V1.? | STC15F2K60S2 | | Supported from BBS-FW version 1.1 V1.? | IAP15F2K61S2 | | Supported from BBS-FW version 1.1 BBS02A - No idea, not tested, not recommended to try unless you have an already bricked controller. ### TSDZ2 Compatible with TSDZ2A/B using the STM microcontroller (which is nearly all off them). ### Displays and Controller Only displays with the Bafang display protocol can work. Also the controllers need to be those, that are officially designed by Bafang, respectively Tongshen. Some shops sell kits with their own controller. ## Legal * Installing this firmware will void your warranty. * I cannot be held responsible for any injuries caused by the use of this firmware, use at your own risk. ================================================ FILE: drawings/pcb/bbshd.sch ================================================ <b>Frames for Sheet and Layout</b> >DRAWING_NAME >LAST_DATE_TIME >SHEET Sheet: <b>FRAME</b><p> DIN A4, landscape with location and doc. field <b>Pin Header Connectors</b><p> <author>Created by librarian@cadsoft.de</author> <b>PIN HEADER</b> >NAME >VALUE <b>PIN HEADER</b> >NAME >VALUE <b>PIN HEADER</b> >NAME >VALUE <b>PIN HEADER</b> >NAME >VALUE <b>PIN HEADER</b> >NAME >VALUE <b>PIN HEADER</b> >NAME >VALUE >NAME >VALUE >NAME >VALUE >NAME >VALUE <b>PIN HEADER</b> <b>PIN HEADER</b> <b>PIN HEADER</b> <b>Supply Symbols</b><p> GND, VCC, 0V, +5V, -5V, etc.<p> Please keep in mind, that these devices are necessary for the automatic wiring of the supply signals.<p> The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> <author>Created by librarian@cadsoft.de</author> >VALUE >VALUE >VALUE >VALUE <b>SUPPLY SYMBOL</b> <b>SUPPLY SYMBOL</b> <b>SUPPLY SYMBOL</b> <b>SUPPLY SYMBOL</b> <b>Diodes</b><p> Based on the following sources: <ul> <li>Motorola : www.onsemi.com <li>Fairchild : www.fairchildsemi.com <li>Philips : www.semiconductors.com <li>Vishay : www.vishay.de </ul> <author>Created by librarian@cadsoft.de</author> <b>SOD-323</b><p> Source: www.st.com, BAT60J.pdf >NAME >VALUE >NAME >VALUE <b>Schottky barrier diode</b><p> Source: www.st.com, BAT60J.pdf <b>Resistors, Capacitors, Inductors</b><p> Based on the previous libraries: <ul> <li>r.lbr <li>cap.lbr <li>cap-fe.lbr <li>captant.lbr <li>polcap.lbr <li>ipc-smd.lbr </ul> All SMD packages are defined according to the IPC specifications and CECC<p> <author>Created by librarian@cadsoft.de</author><p> <p> for Electrolyt Capacitors see also :<p> www.bccomponents.com <p> www.panasonic.com<p> www.kemet.com<p> http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b> <p> for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p> <table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0> <tr valign="top"> <! <td width="10">&nbsp;</td> <td width="90%"> <b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b> <P> <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2> <TR> <TD COLSPAN=8> <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT> </TD> </TR> <TR> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI&nbsp;TECH</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT> </B> </TD> <TD ALIGN=CENTER> <B> <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT> </B> </TD><TD>&nbsp;</TD> </TR> <TR> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 > 3005P<BR> 3006P<BR> 3006W<BR> 3006Y<BR> 3009P<BR> 3009W<BR> 3009Y<BR> 3057J<BR> 3057L<BR> 3057P<BR> 3057Y<BR> 3059J<BR> 3059L<BR> 3059P<BR> 3059Y<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> 89P<BR> 89W<BR> 89X<BR> 89PH<BR> 76P<BR> 89XH<BR> 78SLT<BR> 78L&nbsp;ALT<BR> 56P&nbsp;ALT<BR> 78P&nbsp;ALT<BR> T8S<BR> 78L<BR> 56P<BR> 78P<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> T18/784<BR> 783<BR> 781<BR> -<BR> -<BR> -<BR> 2199<BR> 1697/1897<BR> 1680/1880<BR> 2187<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> 8035EKP/CT20/RJ-20P<BR> -<BR> RJ-20X<BR> -<BR> -<BR> -<BR> 1211L<BR> 8012EKQ&nbsp;ALT<BR> 8012EKR&nbsp;ALT<BR> 1211P<BR> 8012EKJ<BR> 8012EKL<BR> 8012EKQ<BR> 8012EKR<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> 2101P<BR> 2101W<BR> 2101Y<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 2102L<BR> 2102S<BR> 2102Y<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> EVMCOG<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> 43P<BR> 43W<BR> 43Y<BR> -<BR> -<BR> -<BR> -<BR> 40L<BR> 40P<BR> 40Y<BR> 70Y-T602<BR> 70L<BR> 70P<BR> 70Y<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> RT/RTR12<BR> RT/RTR12<BR> RT/RTR12<BR> -<BR> RJ/RJR12<BR> RJ/RJR12<BR> RJ/RJR12<BR></FONT> </TD> </TR> <TR> <TD COLSPAN=8>&nbsp; </TD> </TR> <TR> <TD COLSPAN=8> <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT> </TD> </TR> <TR> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> </TD> </TR> <TR> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 3250L<BR> 3250P<BR> 3250W<BR> 3250X<BR> 3252P<BR> 3252W<BR> 3252X<BR> 3260P<BR> 3260W<BR> 3260X<BR> 3262P<BR> 3262W<BR> 3262X<BR> 3266P<BR> 3266W<BR> 3266X<BR> 3290H<BR> 3290P<BR> 3290W<BR> 3292P<BR> 3292W<BR> 3292X<BR> 3296P<BR> 3296W<BR> 3296X<BR> 3296Y<BR> 3296Z<BR> 3299P<BR> 3299W<BR> 3299X<BR> 3299Y<BR> 3299Z<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> 66P&nbsp;ALT<BR> 66W&nbsp;ALT<BR> 66X&nbsp;ALT<BR> 66P&nbsp;ALT<BR> 66W&nbsp;ALT<BR> 66X&nbsp;ALT<BR> -<BR> 64W&nbsp;ALT<BR> -<BR> 64P&nbsp;ALT<BR> 64W&nbsp;ALT<BR> 64X&nbsp;ALT<BR> 64P<BR> 64W<BR> 64X<BR> 66X&nbsp;ALT<BR> 66P&nbsp;ALT<BR> 66W&nbsp;ALT<BR> 66P<BR> 66W<BR> 66X<BR> 67P<BR> 67W<BR> 67X<BR> 67Y<BR> 67Z<BR> 68P<BR> 68W<BR> 68X<BR> 67Y&nbsp;ALT<BR> 67Z&nbsp;ALT<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 5050<BR> 5091<BR> 5080<BR> 5087<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> T63YB<BR> T63XB<BR> -<BR> -<BR> -<BR> 5887<BR> 5891<BR> 5880<BR> -<BR> -<BR> -<BR> T93Z<BR> T93YA<BR> T93XA<BR> T93YB<BR> T93XB<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 8026EKP<BR> 8026EKW<BR> 8026EKM<BR> 8026EKP<BR> 8026EKB<BR> 8026EKM<BR> 1309X<BR> 1309P<BR> 1309W<BR> 8024EKP<BR> 8024EKW<BR> 8024EKN<BR> RJ-9P/CT9P<BR> RJ-9W<BR> RJ-9X<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 3103P<BR> 3103Y<BR> 3103Z<BR> 3103P<BR> 3103Y<BR> 3103Z<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 3105P/3106P<BR> 3105W/3106W<BR> 3105X/3106X<BR> 3105Y/3106Y<BR> 3105Z/3105Z<BR> 3102P<BR> 3102W<BR> 3102X<BR> 3102Y<BR> 3102Z<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> EVMCBG<BR> EVMCCG<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 55-1-X<BR> 55-4-X<BR> 55-3-X<BR> 55-2-X<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 50-2-X<BR> 50-4-X<BR> 50-3-X<BR> -<BR> -<BR> -<BR> 64P<BR> 64W<BR> 64X<BR> 64Y<BR> 64Z<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> RT/RTR22<BR> RT/RTR22<BR> RT/RTR22<BR> RT/RTR22<BR> RJ/RJR22<BR> RJ/RJR22<BR> RJ/RJR22<BR> RT/RTR26<BR> RT/RTR26<BR> RT/RTR26<BR> RJ/RJR26<BR> RJ/RJR26<BR> RJ/RJR26<BR> RJ/RJR26<BR> RJ/RJR26<BR> RJ/RJR26<BR> RT/RTR24<BR> RT/RTR24<BR> RT/RTR24<BR> RJ/RJR24<BR> RJ/RJR24<BR> RJ/RJR24<BR> RJ/RJR24<BR> RJ/RJR24<BR> RJ/RJR24<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> </TR> <TR> <TD COLSPAN=8>&nbsp; </TD> </TR> <TR> <TD COLSPAN=8> <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> </TD> </TR> <TR> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> </TD> <TD ALIGN=CENTER> <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> </TD> </TR> <TR> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 3323P<BR> 3323S<BR> 3323W<BR> 3329H<BR> 3329P<BR> 3329W<BR> 3339H<BR> 3339P<BR> 3339W<BR> 3352E<BR> 3352H<BR> 3352K<BR> 3352P<BR> 3352T<BR> 3352V<BR> 3352W<BR> 3362H<BR> 3362M<BR> 3362P<BR> 3362R<BR> 3362S<BR> 3362U<BR> 3362W<BR> 3362X<BR> 3386B<BR> 3386C<BR> 3386F<BR> 3386H<BR> 3386K<BR> 3386M<BR> 3386P<BR> 3386S<BR> 3386W<BR> 3386X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 25P<BR> 25S<BR> 25RX<BR> 82P<BR> 82M<BR> 82PA<BR> -<BR> -<BR> -<BR> 91E<BR> 91X<BR> 91T<BR> 91B<BR> 91A<BR> 91V<BR> 91W<BR> 25W<BR> 25V<BR> 25P<BR> -<BR> 25S<BR> 25U<BR> 25RX<BR> 25X<BR> 72XW<BR> 72XL<BR> 72PM<BR> 72RX<BR> -<BR> 72PX<BR> 72P<BR> 72RXW<BR> 72RXL<BR> 72X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> T7YB<BR> T7YA<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> TXD<BR> TYA<BR> TYP<BR> -<BR> TYD<BR> TX<BR> -<BR> 150SX<BR> 100SX<BR> 102T<BR> 101S<BR> 190T<BR> 150TX<BR> 101<BR> -<BR> -<BR> 101SX<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> ET6P<BR> ET6S<BR> ET6X<BR> RJ-6W/8014EMW<BR> RJ-6P/8014EMP<BR> RJ-6X/8014EMX<BR> TM7W<BR> TM7P<BR> TM7X<BR> -<BR> 8017SMS<BR> -<BR> 8017SMB<BR> 8017SMA<BR> -<BR> -<BR> CT-6W<BR> CT-6H<BR> CT-6P<BR> CT-6R<BR> -<BR> CT-6V<BR> CT-6X<BR> -<BR> -<BR> 8038EKV<BR> -<BR> 8038EKX<BR> -<BR> -<BR> 8038EKP<BR> 8038EKZ<BR> 8038EKW<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> 3321H<BR> 3321P<BR> 3321N<BR> 1102H<BR> 1102P<BR> 1102T<BR> RVA0911V304A<BR> -<BR> RVA0911H413A<BR> RVG0707V100A<BR> RVA0607V(H)306A<BR> RVA1214H213A<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 3104B<BR> 3104C<BR> 3104F<BR> 3104H<BR> -<BR> 3104M<BR> 3104P<BR> 3104S<BR> 3104W<BR> 3104X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> EVMQ0G<BR> EVMQIG<BR> EVMQ3G<BR> EVMS0G<BR> EVMQ0G<BR> EVMG0G<BR> -<BR> -<BR> -<BR> EVMK4GA00B<BR> EVM30GA00B<BR> EVMK0GA00B<BR> EVM38GA00B<BR> EVMB6<BR> EVLQ0<BR> -<BR> EVMMSG<BR> EVMMBG<BR> EVMMAG<BR> -<BR> -<BR> EVMMCS<BR> -<BR> -<BR> -<BR> -<BR> -<BR> EVMM1<BR> -<BR> -<BR> EVMM0<BR> -<BR> -<BR> EVMM3<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> 62-3-1<BR> 62-1-2<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> 67R<BR> -<BR> 67P<BR> -<BR> -<BR> -<BR> -<BR> 67X<BR> 63V<BR> 63S<BR> 63M<BR> -<BR> -<BR> 63H<BR> 63P<BR> -<BR> -<BR> 63X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> RJ/RJR50<BR> RJ/RJR50<BR> RJ/RJR50<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> </TR> </TABLE> <P>&nbsp;<P> <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3> <TR> <TD COLSPAN=7> <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT> <P> <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT> </TD> </TR> <TR> <TD> <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> </TD> </TR> <TR> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 3224G<BR> 3224J<BR> 3224W<BR> 3269P<BR> 3269W<BR> 3269X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 44G<BR> 44J<BR> 44W<BR> 84P<BR> 84W<BR> 84X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> ST63Z<BR> ST63Y<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> ST5P<BR> ST5W<BR> ST5X<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> -<BR> -<BR> -<BR> -<BR></FONT> </TD> </TR> <TR> <TD COLSPAN=7>&nbsp; </TD> </TR> <TR> <TD COLSPAN=7> <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> </TD> </TR> <TR> <TD> <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> </TD> <TD> <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> </TD> </TR> <TR> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 3314G<BR> 3314J<BR> 3364A/B<BR> 3364C/D<BR> 3364W/X<BR> 3313G<BR> 3313J<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 23B<BR> 23A<BR> 21X<BR> 21W<BR> -<BR> 22B<BR> 22A<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> ST5YL/ST53YL<BR> ST5YJ/5T53YJ<BR> ST-23A<BR> ST-22B<BR> ST-22<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> ST-4B<BR> ST-4A<BR> -<BR> -<BR> -<BR> ST-3B<BR> ST-3A<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> EVM-6YS<BR> EVM-1E<BR> EVM-1G<BR> EVM-1D<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> G4B<BR> G4A<BR> TR04-3S1<BR> TRG04-2S1<BR> -<BR> -<BR> -<BR></FONT> </TD> <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> -<BR> -<BR> DVR-43A<BR> CVR-42C<BR> CVR-42A/C<BR> -<BR> -<BR></FONT> </TD> </TR> </TABLE> <P> <FONT SIZE=4 FACE=ARIAL><B>ALT =&nbsp;ALTERNATE</B></FONT> <P> &nbsp; <P> </td> </tr> </table> <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> >NAME >VALUE <b>RESISTOR</b> wave soldering<p> >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b> >NAME >VALUE <b>RESISTOR</b><p> wave soldering >NAME >VALUE <b>RESISTOR</b><p> Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf >NAME >VALUE <b>RESISTOR</b> wave soldering<p> Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf >NAME >VALUE <b>RESISTOR</b><p> MELF 0.10 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.25 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.12 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.10 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.25 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.25 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.12 W >NAME >VALUE <b>RESISTOR</b><p> MELF 0.25 W >NAME >VALUE <b>RESISTOR</b><p> type 0204, grid 5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0204, grid 7.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0204, grid 2.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 10 mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 12 mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 15mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 2.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0207, grid 7.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0309, grid 10mm >NAME >VALUE <b>RESISTOR</b><p> type 0309, grid 12.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0309, grid 2.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0411, grid 12.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0411, grid 15 mm >NAME >VALUE <b>RESISTOR</b><p> type 0411, grid 3.81 mm >NAME >VALUE <b>RESISTOR</b><p> type 0414, grid 15 mm >NAME >VALUE <b>RESISTOR</b><p> type 0414, grid 5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0617, grid 17.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0617, grid 22.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0617, grid 5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0922, grid 22.5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0613, grid 5 mm >NAME >VALUE <b>RESISTOR</b><p> type 0613, grid 15 mm >NAME >VALUE <b>RESISTOR</b><p> type 0817, grid 22.5 mm >NAME >VALUE 0817 <b>RESISTOR</b><p> type 0817, grid 6.35 mm >NAME >VALUE 0817 <b>RESISTOR</b><p> type V234, grid 12.5 mm >NAME >VALUE <b>RESISTOR</b><p> type V235, grid 17.78 mm >NAME >VALUE <b>RESISTOR</b><p> type V526-0, grid 2.5 mm >NAME >VALUE <b>CECC Size RC2211</b> Reflow Soldering<p> source Beyschlag >NAME >VALUE <b>CECC Size RC2211</b> Wave Soldering<p> source Beyschlag >NAME >VALUE <b>CECC Size RC3715</b> Reflow Soldering<p> source Beyschlag >NAME >VALUE <b>CECC Size RC3715</b> Wave Soldering<p> source Beyschlag >NAME >VALUE <b>CECC Size RC6123</b> Reflow Soldering<p> source Beyschlag >NAME >VALUE <b>CECC Size RC6123</b> Wave Soldering<p> source Beyschlag >NAME >VALUE <b>RESISTOR</b><p> type 0922, grid 7.5 mm >NAME >VALUE 0922 <b>RESISTOR</b><p> type RDH, grid 15 mm >NAME >VALUE RDH <b>Mini MELF 0102 Axial</b> >NAME >VALUE <b>RESISTOR</b> chip<p> Source: http://www.vishay.com/docs/20008/dcrcw.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RBR52<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RBR53<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RBR54<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RBR55<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RBR56<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RNC55<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p> MIL SIZE RNC60<br> Source: VISHAY .. vta56.pdf >NAME >VALUE <b>Package 4527</b><p> Source: http://www.vishay.com/docs/31059/wsrhigh.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>Wirewound Resistors, Precision Power</b><p> Source: VISHAY wscwsn.pdf >NAME >VALUE <b>CRCW1218 Thick Film, Rectangular Chip Resistors</b><p> Source: http://www.vishay.com .. dcrcw.pdf >NAME >VALUE <b>Chip Monolithic Ceramic Capacitors</b> Medium Voltage High Capacitance for General Use<p> Source: http://www.murata.com .. GRM43DR72E224KW01.pdf >NAME >VALUE <b>PRL1632 are realized as 1W for 3.2 × 1.6mm(1206)</b><p> Source: http://www.mouser.com/ds/2/392/products_18-2245.pdf >NAME >VALUE >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b><p> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 2.4 x 4.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 2.5 x 5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 3 x 5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 4 x 5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 5 x 5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm, outline 6 x 5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 mm + 5 mm, outline 2.4 x 7 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 + 5 mm, outline 2.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 + 5 mm, outline 3.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 + 5 mm, outline 4.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 2.5 + 5 mm, outline 5.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 2.4 x 4.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 2.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 4.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 3 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 5.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 7.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> Horizontal, grid 5 mm, outline 7.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 7.5 mm, outline 3.2 x 10.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 7.5 mm, outline 4.2 x 10.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 7.5 mm, outline 5.2 x 10.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 10.2 mm, outline 4.3 x 13.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 10.2 mm, outline 5.4 x 13.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 10.2 mm, outline 6.4 x 13.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 15 mm, outline 5.4 x 18.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 15 mm, outline 6.4 x 18.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 15 mm, outline 7.2 x 18.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 15 mm, outline 8.4 x 18.3 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 15 mm, outline 9.1 x 18.2 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 22.5 mm, outline 6.2 x 26.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 22.5 mm, outline 7.4 x 26.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 22.5 mm, outline 8.7 x 26.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 22.5 mm, outline 10.8 x 26.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 22.5 mm, outline 11.3 x 26.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 9.3 x 31.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 11.3 x 31.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 13.4 x 31.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 20.5 x 31.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 32.5 mm, outline 13.7 x 37.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 32.5 mm, outline 16.2 x 37.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 32.5 mm, outline 18.2 x 37.4 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 37.5 mm, outline 19.2 x 41.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 37.5 mm, outline 20.3 x 41.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 5 mm, outline 3.5 x 7.5 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 37.5 mm, outline 15.5 x 41.8 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 7.5 mm, outline 6.3 x 10.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 15.4 x 31.6 mm >NAME >VALUE <b>CAPACITOR</b><p> grid 27.5 mm, outline 17.3 x 31.6 mm >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 0204 reflow solder</b><p> Metric Code Size 1005 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 0603 reflow solder</b><p> Metric Code Size 1608 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 0805 reflow solder</b><p> Metric Code Size 2012 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 1206 reflow solder</b><p> Metric Code Size 3216 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 1210 reflow solder</b><p> Metric Code Size 3225 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 1812 reflow solder</b><p> Metric Code Size 4532 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 1825 reflow solder</b><p> Metric Code Size 4564 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 2220 reflow solder</b><p>Metric Code Size 5650 >NAME >VALUE <b>Ceramic Chip Capacitor KEMET 2225 reflow solder</b><p>Metric Code Size 5664 >NAME >VALUE <b> </b><p> Source: http://www.vishay.com/docs/10129/hpc0201a.pdf >NAME >VALUE Source: http://www.avxcorp.com/docs/catalogs/cx5r.pdf >NAME >VALUE <b>CAPACITOR</b><p> Source: AVX .. aphvc.pdf >NAME >VALUE <b>CAPACITOR</b><p> Source: AVX .. aphvc.pdf >NAME >VALUE <b>CAPACITOR</b> >NAME >VALUE >NAME >VALUE >NAME >VALUE <B>RESISTOR</B>, European symbol <B>CAPACITOR</B>, European symbol <b>Linear Devices</b><p> Operational amplifiers, comparators, voltage regulators, ADCs, DACs, etc.<p> <author>Created by librarian@cadsoft.de</author> <b>Dual In Line Package</b> >NAME >VALUE <b>Small Outline Package 8</b><br> NS Package M08A >NAME >VALUE >NAME >VALUE V+ V- <b>OP AMP</b> also LM158; LM258; LM2904<p> Source: http://cache.national.com/ds/LM/LM158.pdf <b>LEDs</b><p> <author>Created by librarian@cadsoft.de</author><br> Extended by Federico Battaglin <author>&lt;federico.rd@fdpinternational.com&gt;</author> with DUOLED <b>CHICAGO MINIATURE LAMP, INC.</b><p> 7022X Series SMT LEDs 1206 Package Size >NAME >VALUE <B>LED</B><p> 5 mm, square, Siemens >NAME >VALUE <B>LED</B><p> 2 x 5 mm, rectangle >NAME >VALUE <B>LED</B><p> 3 mm, round >NAME >VALUE <B>LED</B><p> 5 mm, round >NAME >VALUE <B>LED</B><p> 1 mm, round, Siemens >NAME >VALUE <B>LED BLOCK</B><p> 1 LED, Siemens >NAME >VALUE <b>LED HOLDER</b><p> Siemens >NAME >VALUE <b>LED HOLDER</b><p> Siemens >NAME >VALUE <b>LED HOLDER</b><p> Siemens A+ K- >NAME >VALUE <b>LED HOLDER</b><p> Siemens >NAME >VALUE + - <B>IR LED</B><p> infrared emitting diode, Infineon TO-18, lead spacing 2.54 mm, cathode marking<p> Inifineon >NAME >VALUE <B>IR LED</B><p> infrared emitting diode, Infineon TO-18, lead spacing 2.54 mm, cathode marking<p> Inifineon >NAME >VALUE <B>LED</B><p> rectangle, 5.7 x 3.2 mm >NAME >VALUE <B>IR LED</B><p> IR transmitter Siemens >NAME >VALUE <b>TOPLED® High-optical Power LED (HOP)</b><p> Source: http://www.osram.convergy.de/ ... ls_t675.pdf >NAME >VALUE A C <b>BLUE LINETM Hyper Mini TOPLED® Hyper-Bright LED</b><p> Source: http://www.osram.convergy.de/ ... LB M676.pdf A C >NAME >VALUE <b>Super SIDELED® High-Current LED</b><p> LG A672, LP A672 <br> Source: http://www.osram.convergy.de/ ... LG_LP_A672.pdf (2004.05.13) C A >NAME >VALUE <b>SmartLEDTM Hyper-Bright LED</b><p> Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY L896.pdf >NAME >VALUE <b>Hyper TOPLED® RG Hyper-Bright LED</b><p> Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY T776.pdf >NAME >VALUE A C <b>Hyper Micro SIDELED®</b><p> Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY Y876.pdf >NAME >VALUE <b>Power TOPLED®</b><p> Source: http://www.osram.convergy.de/ ... LA_LO_LA_LY E67B.pdf >NAME >VALUE C A C C <b>Hyper CHIPLED Hyper-Bright LED</b><p> LB Q993<br> Source: http://www.osram.convergy.de/ ... Lb_q993.pdf >NAME >VALUE <b>Hyper CHIPLED Hyper-Bright LED</b><p> LB R99A<br> Source: http://www.osram.convergy.de/ ... lb_r99a.pdf >NAME >VALUE <b>Mini TOPLED Santana®</b><p> Source: http://www.osram.convergy.de/ ... LG M470.pdf >NAME >VALUE <b>CHIPLED</b><p> Source: http://www.osram.convergy.de/ ... LG_R971.pdf >NAME >VALUE <b>CHIPLED</b><p> Source: http://www.osram.convergy.de/ ... LG_LY N971.pdf >NAME >VALUE <b>CHIPLED</b><p> Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf >NAME >VALUE <b>CHIPLED-0603</b><p> Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> Package able to withstand TTW-soldering heat<br> Package suitable for TTW-soldering<br> Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf >NAME >VALUE <b>SmartLED TTW</b><p> Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> Package able to withstand TTW-soldering heat<br> Package suitable for TTW-soldering<br> Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf >NAME >VALUE <b>Lumileds Lighting. LUXEON®</b> with cool pad<p> Source: K2.pdf >NAME >VALUE <b>Lumileds Lighting. LUXEON®</b> without cool pad<p> Source: K2.pdf >NAME >VALUE <B>LED</B><p> 10 mm, round >NAME >VALUE <b>SURFACE MOUNT LED LAMP</b> 3.5x2.8mm<p> Source: http://www.kingbright.com/manager/upload/pdf/KA-3528ASYC(Ver1189474662.1) >NAME >VALUE <b>SML0805-2CW-TR (0805 PROFILE)</b> COOL WHITE<p> Source: http://www.ledtronics.com/ds/smd-0603/Dstr0093.pdf >NAME >VALUE <b>SML10XXKH-TR (HIGH INTENSITY) LED</b><p> <table> <tr><td>SML10R3KH-TR</td><td>ULTRA RED</td></tr> <tr><td>SML10E3KH-TR</td><td>SUPER REDSUPER BLUE</td></tr> <tr><td>SML10O3KH-TR</td><td>SUPER ORANGE</td></tr> <tr><td>SML10PY3KH-TR</td><td>PURE YELLOW</td></tr> <tr><td>SML10OY3KH-TR</td><td>ULTRA YELLOW</td></tr> <tr><td>SML10AG3KH-TR</td><td>AQUA GREEN</td></tr> <tr><td>SML10BG3KH-TR</td><td>BLUE GREEN</td></tr> <tr><td>SML10PB1KH-TR</td><td>SUPER BLUE</td></tr> <tr><td>SML10CW1KH-TR</td><td>WHITE</td></tr> </table> Source: http://www.ledtronics.com/ds/smd-1206/dstr0094.PDF >NAME >VALUE <b>SML0603-XXX (HIGH INTENSITY) LED</b><p> <table> <tr><td>AG3K</td><td>AQUA GREEN</td></tr> <tr><td>B1K</td><td>SUPER BLUE</td></tr> <tr><td>R1K</td><td>SUPER RED</td></tr> <tr><td>R3K</td><td>ULTRA RED</td></tr> <tr><td>O3K</td><td>SUPER ORANGE</td></tr> <tr><td>O3KH</td><td>SOFT ORANGE</td></tr> <tr><td>Y3KH</td><td>SUPER YELLOW</td></tr> <tr><td>Y3K</td><td>SUPER YELLOW</td></tr> <tr><td>2CW</td><td>WHITE</td></tr> </table> Source: http://www.ledtronics.com/ds/smd-0603/Dstr0092.pdf >NAME >VALUE >NAME >VALUE <b>LED</b><p> <u>OSRAM</u>:<br> - <u>CHIPLED</u><br> LG R971, LG N971, LY N971, LG Q971, LY Q971, LO R971, LY R971 LH N974, LH R974<br> LS Q976, LO Q976, LY Q976<br> LO Q996<br> - <u>Hyper CHIPLED</u><br> LW Q18S<br> LB Q993, LB Q99A, LB R99A<br> - <u>SideLED</u><br> LS A670, LO A670, LY A670, LG A670, LP A670<br> LB A673, LV A673, LT A673, LW A673<br> LH A674<br> LY A675<br> LS A676, LA A676, LO A676, LY A676, LW A676<br> LS A679, LY A679, LG A679<br> - <u>Hyper Micro SIDELED®</u><br> LS Y876, LA Y876, LO Y876, LY Y876<br> LT Y87S<br> - <u>SmartLED</u><br> LW L88C, LW L88S<br> LB L89C, LB L89S, LG L890<br> LS L89K, LO L89K, LY L89K<br> LS L896, LA L896, LO L896, LY L896<br> - <u>TOPLED</u><br> LS T670, LO T670, LY T670, LG T670, LP T670<br> LSG T670, LSP T670, LSY T670, LOP T670, LYG T670<br> LG T671, LOG T671, LSG T671<br> LB T673, LV T673, LT T673, LW T673<br> LH T674<br> LS T676, LA T676, LO T676, LY T676, LB T676, LH T676, LSB T676, LW T676<br> LB T67C, LV T67C, LT T67C, LS T67K, LO T67K, LY T67K, LW E67C<br> LS E67B, LA E67B, LO E67B, LY E67B, LB E67C, LV E67C, LT E67C<br> LW T67C<br> LS T679, LY T679, LG T679<br> LS T770, LO T770, LY T770, LG T770, LP T770<br> LB T773, LV T773, LT T773, LW T773<br> LH T774<br> LS E675, LA E675, LY E675, LS T675<br> LS T776, LA T776, LO T776, LY T776, LB T776<br> LHGB T686<br> LT T68C, LB T68C<br> - <u>Hyper Mini TOPLED®</u><br> LB M676<br> - <u>Mini TOPLED Santana®</u><br> LG M470<br> LS M47K, LO M47K, LY M47K <p> Source: http://www.osram.convergy.de<p> <u>LUXEON:</u><br> - <u>LUMILED®</u><br> LXK2-PW12-R00, LXK2-PW12-S00, LXK2-PW14-U00, LXK2-PW14-V00<br> LXK2-PM12-R00, LXK2-PM12-S00, LXK2-PM14-U00<br> LXK2-PE12-Q00, LXK2-PE12-R00, LXK2-PE12-S00, LXK2-PE14-T00, LXK2-PE14-U00<br> LXK2-PB12-K00, LXK2-PB12-L00, LXK2-PB12-M00, LXK2-PB14-N00, LXK2-PB14-P00, LXK2-PB14-Q00<br> LXK2-PR12-L00, LXK2-PR12-M00, LXK2-PR14-Q00, LXK2-PR14-R00<br> LXK2-PD12-Q00, LXK2-PD12-R00, LXK2-PD12-S00<br> LXK2-PH12-R00, LXK2-PH12-S00<br> LXK2-PL12-P00, LXK2-PL12-Q00, LXK2-PL12-R00 <p> Source: www.luxeon.com<p> <u>KINGBRIGHT:</U><p> KA-3528ASYC<br> Source: www.kingbright.com <b>PTC and NTC Resistors</b><p> Siemens, Philips, Valvo<p> <author>Created by librarian@cadsoft.de</author> <b>PHILIPS NTC</b> >NAME >VALUE <b>PHILIPS/VALVO NTC</b> >NAME >VALUE >NAME >VALUE <b>PHILIPS NTC</b> <b>PHILIPS NTC</b> Main Harness Signal Connector Brake Throttle RX TX GND 5V RX TX Components missing, located on the bottom side of pcb right under STC MCU. Two SOT-23, likely two transistors, some form of input protection maybe? PAS1 PAS2 Debug Terminalt? Constant data output at 9600 baud. Gear sensor ??? Has not been traced ??? Has not been traced SPD Daniel Nilsson ADC6 - Battery voltage measurement TxD4 RxD4 RxD3 TxD3 Another UART brought out to pins, no data has been seen. ADC7 - Temperature sensor U (white) V (blue) W (grey) Motor Power Enable NEC TxD STC RxD2 STC TxD2 NEC RxD Serial Communication between MCUs Daniel Nilsson WARNING: Not sure this opamp circuit is 100% correct, it looks a bit strange. OPAMP is there to amplify voltage drop over shunt resistors in order to get a more detailed reading with ADC. Motor winding temperature sensor. Labeled as "T" on hall sensor board. Some form of status LED. Seems to be blinking during normal operation. Motor Control Enable No effect, but should be high Since Version 6.2.2 text objects can contain more than one line, which will not be processed correctly with this version. ================================================ FILE: drawings/pcb/eagle.epf ================================================ [Eagle] Version="07 05 00" Platform="Windows" Serial="62191E841E-LSR-WLM-1EL" Globals="Globals" Desktop="Desktop" [Globals] AutoSaveProject=1 UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/19inch.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/40xx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/41xx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/45xx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74ac-logic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74ttl-din.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74xx-eu.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74xx-little-de.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74xx-little-us.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/74xx-us.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/751xx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/IQD-Frequency-Products.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/advanced-test-technologies.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/agilent-technologies.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/allegro.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/altera-cyclone-II.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/altera-cyclone-III.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/altera-stratix-iv.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/altera.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/am29-memory.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/amd-mach.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/amd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/amis.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/analog-devices.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/aplus.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ase.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/atmel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/austriamicrosystems.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/avago.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/axis.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/battery.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/belton-engineering.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/burr-brown.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/busbar.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/buzzer.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/c-trimm.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/california-micro-devices.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/capacitor-wima.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/chipcard-siemens.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/cirrus-logic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-3m.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-4ucon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-champ.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-micromatch.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-mt.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-mt6.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-quick.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp-te.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-amphenol.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-avx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-berg.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-bosch.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-chipcard-iso7816.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-coax.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-commcon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-conrad.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-cpci.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-cui.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-cypressindustries.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-deutsch.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-dil.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-ebyelectro.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-elco.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-erni.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-faston.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-fci.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-friwo.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-garry.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-harting-h.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-harting-ml.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-harting-v.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-harting.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-hirose.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-hirschmann.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-jack.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-jae.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-jst.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-kycon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-kyocera-elco.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-lemo.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-leotronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-lsta.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-lstb.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-lumberg.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-ml.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-molex.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-neutrik_ag.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-omron.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-panasonic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-panduit.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-pc.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-pc104.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-254.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-3.81.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-350.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-500.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-508.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-762.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-me_max.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-mkds_5.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-phoenix-smkdsp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-ptr500.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-pulse.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-rib.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-samtec.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-shallin.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-shiua-chyuan.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-stewart.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-stocko.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-subd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-sullinselectronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-thomas-betts.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-tyco.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-tycoelectronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-vg.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-wago-500.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-wago-508.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-wago.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-wago255.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-weidmueller-sl35.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-wenzhou-yihua.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-xmultiple.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/con-yamaichi.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/crystal.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/csr.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/cypress.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/davicom.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/dc-dc-converter.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/dimensions.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/diode.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/discrete.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/display-hp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/display-kingbright.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/display-lcd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/docu-dummy.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/dom-key.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/eagle-ltspice.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ecl.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/em-microelectronic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/etx-board.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/exar.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fairchild-semic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/farnell.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fiber-optic-hp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fiber-optic-siemens.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fifo.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/flexipanel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fox-electronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/frames.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/freescale.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ftdichip.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fujitsu.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/fuse.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/gennum.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/halo-electronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/heatsink.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/holes.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/holtek.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ic-package.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/inductor-coilcraft.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/inductor-neosid.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/inductor-nkl.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/inductors.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/infineon-tricore.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/infineon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/intersil-techwell.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/intersil.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ir.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/isd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/johanson-technology.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/jump-0r-smd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/jumper.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lantronix.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lattice.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lc-filter.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/led-7-segment.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/led-citizen-electronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/led-lumiled.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/led.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lem.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/linear-technology.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/linear.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/linx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/logo.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lprs.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lsi-computer-systems.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/lumiled.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/marks.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/maxim.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/maxstream.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/melexis.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-hitachi.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-idt.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-micron.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-motorola-dram.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-nec.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-samsung.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory-sram.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/memory.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/mems.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micrel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-cyrod.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-fujitsu.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-harris.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-hitachi.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-infineon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-intel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-mc68000.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-motorola.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-philips.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-renesas.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-samsung.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micro-siemens.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/microchip.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micron.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/micronas.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/microphon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/microwave.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/midori-sensor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/minicircuits.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/mitsubishi-semiconductor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/motorola-sensor-driver.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/murata-filter.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/murata-sensor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/nanotec.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/national-instruments.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/national-semiconductor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/nec-lqfp100-pack.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/nec.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/nrj-semiconductor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/omnivision.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/on-semiconductor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-honeywell-3000.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-honeywell-4000.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-honeywell.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-micro-linear.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-trans-siemens.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-transmittter-hp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/opto-vishay.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/optocoupler.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pal.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/philips-semiconductors.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/photo-elements.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/piher.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pinhead.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/plcc-socket.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pld-intel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/plxtech.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pot-vitrohm.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pot-xicor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/pot.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ptc-ntc.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/quantum-research-group.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/rcl.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/recom-international.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/rectifier.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ref-packages-longpad.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/ref-packages.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/relay.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/renesas.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-bourns.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-dil.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-net.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-power.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-ruf.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-shunt.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor-sil.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/resistor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/rf-micro-devices.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/rf-solutions.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/rohm.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/roundsolutions.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/semicon-smd-ipc.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sensor-comus-group.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sensor-heraeus.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sensor-infratec.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sharp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/silabs.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sim-technology.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/sipex.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/smd-ipc.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/smd-special.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/solomon-systech.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/solpad.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/speaker.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/special-drill.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/special.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/st-microelectronics.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/stm32xx.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/supertex.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/supply1.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/supply2.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-alps.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-coto.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-dil.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-misc.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-omron.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-raychem.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch-reed.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/switch.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/telcom.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/telecontrolli.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/telefunken.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/testpad.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/texas-sn55-sn75.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/texas.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/toshiba.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/traco-electronic.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trafo-bei.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trafo-hammondmfg.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trafo-siemens.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trafo-xicon.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trafo.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transformer-pulse.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-fet.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-neu-to92.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-npn.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-pnp.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-power.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor-small-signal.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/transistor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/triac.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/trimble.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/tripas.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/u-blox.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/uln-udn.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/v-reg-micrel.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/v-reg.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/varistor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/wafer-scale-psd.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/wirepad.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/xicor.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/xilinx-virtex-v5.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/xilinx-xc18v.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/xilinx-xc9.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/xilinx-xcv.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/zetex.lbr" UsedLibrary="C:/Program Files/EAGLE-7.5.0/lbr/zilog.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/adafruit.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/bss138_10.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/con-jst2.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/con-usb-2.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/con-usb-3.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/con-usb.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/esp32.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/esp8266-esp12.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/ic.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/microusb.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/motor-driver.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/photo-interrupter.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/potentiometers.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/regulators.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/smps.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/stm32.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/switch-tact.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/power-ic.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Aesthetics.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Batteries.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Boards.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Capacitors.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Clocks.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Coils.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Connectors.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-DigitalIC.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-DiscreteSemi.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Displays.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Electromechanical.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-FreqCtrl.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Fuses.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-GPS.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Hardware.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Amplifiers.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Comms.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Conversion.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Logic.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Memory.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Microcontroller.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Power.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-IC-Special-Function.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Jumpers.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-LED.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-PowerSymbols.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Resistors.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Retired.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-RF.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Switches.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/SparkFun-Sensors.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/sparkfun/User-Submitted.lbr" UsedLibrary="D:/Projects/Git/components/eagle-lbr/element14/atmel_element14.lbr" [Win_1] Type="Control Panel" Loc="-8 -8 2551 1368" State=1 Number=0 [Desktop] Screen="2560 1440" Window="Win_1" ================================================ FILE: src/firmware/.gitignore ================================================ **/*.asm **/*.elf **/*.ihx **/*.cdb **/*.lk **/*.map **/*.adb **/*.lst **/*.rel **/*.rst **/*.sym *.hex *.mem .vs build *.vcxproj.user ================================================ FILE: src/firmware/Makefile ================================================ .PHONY: all clean ifeq '$(findstring ;,$(PATH))' ';' UNAME := Windows else UNAME := $(shell uname 2>/dev/null || echo Unknown) endif # Select target controller (normally done from cmd line): #TARGET_CONTROLLER = BBSHD #TARGET_CONTROLLER = BBS02 #TARGET_CONTROLLER = TSDZ2 # Compiler CC = sdcc # Target name TARGET = bbs-fw MAINSRC = main.c SUBDIRS = CFLAGS = -Ddouble=float --std-c99 -D$(TARGET_CONTROLLER) # Target Specific ifeq ($(TARGET_CONTROLLER), BBSHD) CFLAGS += -mmcs51 --model-large --xram-size 3840 SUBDIRS += bbsx endif ifeq ($(TARGET_CONTROLLER), BBS02) CFLAGS += -mmcs51 --model-large --xram-size 1792 SUBDIRS += bbsx endif ifeq ($(TARGET_CONTROLLER), TSDZ2) CFLAGS += -mstm8 SUBDIRS += tsdz2 endif INCS = $(wildcard *.h $(foreach fd, $(SUBDIRS), $(fd)/*.h)) SRCS = $(filter-out main.c, $(wildcard *.c $(foreach fd, $(SUBDIRS), $(fd)/*.c))) RELS := $(SRCS:.c=.rel) INC_DIRS = -I./ $(addprefix -I, $(SUBDIRS)) all: precheck $(TARGET) hex $(TARGET): $(MAINSRC) $(RELS) $(CC) -o $(TARGET).ihx $(INC_DIRS) $(CFLAGS) $(MAINSRC) $(RELS) %.rel: %.c $(INCS) $(CC) -o $@ -c $(INC_DIRS) $(CFLAGS) $< echo: $(info SRCS: $(SRCS)) $(info RELS: $(RELS)) $(info INCS: $(INCS)) precheck: ifndef TARGET_CONTROLLER $(info TARGET_CONTROLLER is not specified.) $(info Set to one of [BBSHD, BBS02, TSDZ2]) $(info Example:) $(info $(null) make all TARGET_CONTROLLER=BBSHD) $(error ) endif $(info Building bbs-fw for $(TARGET_CONTROLLER)) hex: ifeq ($(UNAME), Linux) @packihx bbs-fw.ihx > bbs-fw.hex else @cmd /C tohex.bat endif clean: ifeq ($(UNAME), Linux) @rm -f bbsx/*.hex tsdz2/*.hex *.hex @rm -f bbsx/*.ihx tsdz2/*.ihx *.ihx @rm -f bbsx/*.asm tsdz2/*.asm *.asm @rm -f bbsx/*.rel tsdz2/*.rel *.rel @rm -f bbsx/*.lk tsdz2/*.lk *.lk @rm -f bbsx/*.lst tsdz2/*.lst *.lst @rm -f bbsx/*.rst tsdz2/*.rst *.rst @rm -f bbsx/*.sym tsdz2/*.sym *.sym @rm -f bbsx/*.cdb tsdz2/*.cdb *.cdb @rm -f bbsx/*.map tsdz2/*.map *.map @rm -f bbsx/*.elf tsdz2/*.elf *.elf @rm -f bbsx/*.adb tsdz2/*.adb *.adb @rm -f bbsx/*.mem tsdz2/*.mem *.mem else @cmd /C clean.bat endif $(info Clean Finished) .PHONY = all hex clean precheck echo .SUFFIXES: .c .rel ================================================ FILE: src/firmware/adc.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _ADC_H_ #define _ADC_H_ #include void adc_init(); void adc_process(); uint8_t adc_get_throttle(); uint16_t adc_get_torque(); uint16_t adc_get_temperature_contr(); uint16_t adc_get_temperature_motor(); uint16_t adc_get_battery_voltage(); #endif ================================================ FILE: src/firmware/app.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "app.h" #include "fwconfig.h" #include "cfgstore.h" #include "motor.h" #include "sensors.h" #include "throttle.h" #include "lights.h" #include "uart.h" #include "eventlog.h" #include "util.h" #include "system.h" typedef struct { assist_level_t level; // cached precomputed values // --------------------------------- // speed int32_t max_wheel_speed_rpm_x10; // pas uint8_t keep_current_target_percent; uint16_t keep_current_ramp_start_rpm_x10; uint16_t keep_current_ramp_end_rpm_x10; } assist_level_data_t; static uint8_t assist_level; static uint8_t operation_mode; static uint16_t global_speed_limit_rpm; static int32_t global_throttle_speed_limit_rpm_x10; static uint16_t lvc_voltage_x100; static uint16_t lvc_ramp_down_start_voltage_x100; static uint16_t lvc_ramp_down_end_voltage_x100; static assist_level_data_t assist_level_data; static uint16_t speed_limit_ramp_interval_rpm_x10; static bool cruise_paused; static int8_t temperature_contr_c; static int8_t temperature_motor_c; static uint16_t ramp_up_current_interval_ms; static uint32_t power_blocked_until_ms; static uint16_t pretension_cutoff_speed_rpm_x10; static bool lights_state = false; void apply_pas_cadence(uint8_t* target_current, uint8_t throttle_percent); #if HAS_TORQUE_SENSOR void apply_pas_torque(uint8_t* target_current); #endif void apply_pretension(uint8_t* target_current); void apply_cruise(uint8_t* target_current, uint8_t throttle_percent); bool apply_throttle(uint8_t* target_current, uint8_t throttle_percent); bool apply_speed_limit(uint8_t* target_current, uint8_t throttle_percent, bool pas_engaged, bool throttle_override); bool apply_thermal_limit(uint8_t* target_current); bool apply_low_voltage_limit(uint8_t* target_current); bool apply_shift_sensor_interrupt(uint8_t* target_current); bool apply_brake(uint8_t* target_current); void apply_current_ramp_up(uint8_t* target_current, bool enable); void apply_current_ramp_down(uint8_t* target_current, bool enable); bool check_power_block(); void block_power_for(uint16_t ms); void reload_assist_params(); uint16_t convert_wheel_speed_kph_to_rpm(uint8_t speed_kph); void app_init() { motor_disable(); lights_disable(); lights_set(g_config.lights_mode == LIGHTS_MODE_ALWAYS_ON); lvc_voltage_x100 = g_config.low_cut_off_v * 100u; uint16_t full_voltage_range_x100 = EXPAND_U16(g_config.max_battery_x100v_u16h, g_config.max_battery_x100v_u16l) - lvc_voltage_x100; uint16_t padded_voltage_range_x100 = (uint16_t)(full_voltage_range_x100 * (100 - BATTERY_FULL_OFFSET_PERCENT - BATTERY_EMPTY_OFFSET_PERCENT) / 100); lvc_ramp_down_end_voltage_x100 = (uint16_t)(lvc_voltage_x100 + (full_voltage_range_x100 * BATTERY_EMPTY_OFFSET_PERCENT / 100)); lvc_ramp_down_start_voltage_x100 = (uint16_t)(lvc_ramp_down_end_voltage_x100 + ((padded_voltage_range_x100 * LVC_RAMP_DOWN_OFFSET_PERCENT) / 100)); global_speed_limit_rpm = 0; global_throttle_speed_limit_rpm_x10 = 0; temperature_contr_c = 0; temperature_motor_c = 0; ramp_up_current_interval_ms = (g_config.max_current_amps * 10u) / g_config.current_ramp_amps_s; power_blocked_until_ms = 0; speed_limit_ramp_interval_rpm_x10 = convert_wheel_speed_kph_to_rpm(SPEED_LIMIT_RAMP_DOWN_INTERVAL_KPH) * 10; pretension_cutoff_speed_rpm_x10 = convert_wheel_speed_kph_to_rpm(g_config.pretension_speed_cutoff_kph) * 10; cruise_paused = true; operation_mode = OPERATION_MODE_DEFAULT; app_set_wheel_max_speed_rpm(convert_wheel_speed_kph_to_rpm(g_config.max_speed_kph)); app_set_assist_level(g_config.assist_startup_level); reload_assist_params(); if (g_config.assist_mode_select == ASSIST_MODE_SELECT_BRAKE_BOOT && brake_is_activated()) { app_set_operation_mode(OPERATION_MODE_SPORT); } } void app_process() { uint8_t target_current = 0; uint8_t target_cadence = assist_level_data.level.max_cadence_percent; uint8_t throttle_percent = throttle_map_response(throttle_read()); bool pas_engaged = false; bool throttle_override = false; if (check_power_block()) { target_current = 0; } else if (assist_level == ASSIST_PUSH && g_config.use_push_walk) { target_current = 10; } else { apply_pretension(&target_current); apply_pas_cadence(&target_current, throttle_percent); #if HAS_TORQUE_SENSOR apply_pas_torque(&target_current); #endif // HAS_TORQUE_SENSOR pas_engaged = target_current > 0; apply_cruise(&target_current, throttle_percent); throttle_override = apply_throttle(&target_current, throttle_percent); // override target cadence if configured in assist level if (throttle_override && (assist_level_data.level.flags & ASSIST_FLAG_PAS) && (assist_level_data.level.flags & ASSIST_FLAG_OVERRIDE_CADENCE)) { target_cadence = THROTTLE_CADENCE_OVERRIDE_PERCENT; } } bool speed_limiting = apply_speed_limit(&target_current, throttle_percent, pas_engaged, throttle_override); bool thermal_limiting = apply_thermal_limit(&target_current); bool lvc_limiting = apply_low_voltage_limit(&target_current); bool shift_limiting = #if HAS_SHIFT_SENSOR_SUPPORT apply_shift_sensor_interrupt(&target_current); #else false; #endif bool is_limiting = speed_limiting || thermal_limiting || lvc_limiting || shift_limiting; bool is_braking = apply_brake(&target_current); apply_current_ramp_up(&target_current, is_limiting || !throttle_override); apply_current_ramp_down(&target_current, !is_braking && !shift_limiting); motor_set_target_speed(target_cadence); motor_set_target_current(target_current); if (target_current > 0) { motor_enable(); } else { motor_disable(); } if (g_config.lights_mode == LIGHTS_MODE_DISABLED /*|| (motor_status() & MOTOR_ERROR_LVC) */) { lights_disable(); } else { lights_enable(); } } void app_set_assist_level(uint8_t level) { if (assist_level != level) { if (assist_level == ASSIST_PUSH && g_config.use_push_walk) { // When releasig push walk mode pedals may have been rotating // with the motor, block motor power for 2 seconds to prevent PAS // sensor from incorrectly applying power if returning to a PAS level. block_power_for(1000); } assist_level = level; eventlog_write_data(EVT_DATA_ASSIST_LEVEL, assist_level); reload_assist_params(); } } void app_set_lights(bool on) { if ( // it's ok to write ugly code if you say it's ugly... (g_config.assist_mode_select == ASSIST_MODE_SELECT_LIGHTS) || (assist_level == ASSIST_0 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS0_LIGHT) || (assist_level == ASSIST_1 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS1_LIGHT) || (assist_level == ASSIST_2 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS2_LIGHT) || (assist_level == ASSIST_3 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS3_LIGHT) || (assist_level == ASSIST_4 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS4_LIGHT) || (assist_level == ASSIST_5 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS5_LIGHT) || (assist_level == ASSIST_6 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS6_LIGHT) || (assist_level == ASSIST_7 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS7_LIGHT) || (assist_level == ASSIST_8 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS8_LIGHT) || (assist_level == ASSIST_9 && g_config.assist_mode_select == ASSIST_MODE_SELECT_PAS9_LIGHT) ) { if (on) { app_set_operation_mode(OPERATION_MODE_SPORT); } else { app_set_operation_mode(OPERATION_MODE_DEFAULT); } } else { if (g_config.lights_mode == LIGHTS_MODE_DEFAULT && lights_state != on) { lights_state = on; eventlog_write_data(EVT_DATA_LIGHTS, on); lights_set(on); } } } void app_set_operation_mode(uint8_t mode) { if (operation_mode != mode) { operation_mode = mode; eventlog_write_data(EVT_DATA_OPERATION_MODE, operation_mode); reload_assist_params(); } } void app_set_wheel_max_speed_rpm(uint16_t value) { if (global_speed_limit_rpm != value) { global_speed_limit_rpm = value; global_throttle_speed_limit_rpm_x10 = ((int32_t)global_speed_limit_rpm * g_config.throttle_global_spd_lim_percent) / 10; eventlog_write_data(EVT_DATA_WHEEL_SPEED_PPM, value); reload_assist_params(); } } uint8_t app_get_assist_level() { return assist_level; } uint8_t app_get_lights() { return lights_state; } uint8_t app_get_status_code() { uint16_t motor = motor_status(); if (motor & MOTOR_ERROR_HALL_SENSOR) { return STATUS_ERROR_HALL_SENSOR; } if (motor & MOTOR_ERROR_CURRENT_SENSE) { return STATUS_ERROR_CURRENT_SENSE; } if (motor & MOTOR_ERROR_POWER_RESET) { // Phase line error code reused, cause and meaning // of MOTOR_ERROR_POWER_RESET triggered on bbs02 is currently unknown return STATUS_ERROR_PHASE_LINE; } if (!throttle_ok()) { return STATUS_ERROR_THROTTLE; } if (!torque_sensor_ok()) { return STATUS_ERROR_TORQUE_SENSOR; } if (temperature_motor_c > MAX_TEMPERATURE) { return STATUS_ERROR_MOTOR_OVER_TEMP; } if (temperature_contr_c > MAX_TEMPERATURE) { return STATUS_ERROR_CONTROLLER_OVER_TEMP; } // Disable LVC error since it is not shown on display in original firmware // Uncomment if you want to enable // if (motor & MOTOR_ERROR_LVC) // { // return STATUS_ERROR_LVC; // } if (brake_is_activated()) { return STATUS_BRAKING; } return STATUS_NORMAL; } uint8_t app_get_temperature() { int8_t temp_max = MAX(temperature_contr_c, temperature_motor_c); if (temp_max < 0) { return 0; } return (uint8_t)temp_max; } void apply_pretension(uint8_t* target_current) { uint16_t current_speed_rpm_x10 = speed_sensor_get_rpm_x10(); if (g_config.use_speed_sensor && g_config.use_pretension && current_speed_rpm_x10 > pretension_cutoff_speed_rpm_x10) { *target_current = 1; } return; } void apply_pas_cadence(uint8_t* target_current, uint8_t throttle_percent) { if ((assist_level_data.level.flags & ASSIST_FLAG_PAS) && !(assist_level_data.level.flags & ASSIST_FLAG_PAS_TORQUE)) { if (pas_is_pedaling_forwards() && pas_get_pulse_counter() > g_config.pas_start_delay_pulses) { if (assist_level_data.level.flags & ASSIST_FLAG_PAS_VARIABLE) { uint8_t current = (uint8_t)MAP16(throttle_percent, 0, 100, 0, assist_level_data.level.target_current_percent); if (current > *target_current) { *target_current = current; } } else { if (assist_level_data.level.target_current_percent > *target_current) { *target_current = assist_level_data.level.target_current_percent; } // apply "keep current" ramp if (g_config.pas_keep_current_percent < 100) { if (*target_current > assist_level_data.keep_current_target_percent && pas_get_cadence_rpm_x10() > assist_level_data.keep_current_ramp_start_rpm_x10) { uint32_t cadence = MIN(pas_get_cadence_rpm_x10(), assist_level_data.keep_current_ramp_end_rpm_x10); // ramp down current towards keep_current_target_percent with rpm above keep_current_ramp_start_rpm_x10 *target_current = MAP32( cadence, // in assist_level_data.keep_current_ramp_start_rpm_x10, // in_min assist_level_data.keep_current_ramp_end_rpm_x10, // in_max *target_current, // out_min assist_level_data.keep_current_target_percent); // out_max } } } } } } #if HAS_TORQUE_SENSOR void apply_pas_torque(uint8_t* target_current) { if ((assist_level_data.level.flags & ASSIST_FLAG_PAS) && (assist_level_data.level.flags & ASSIST_FLAG_PAS_TORQUE)) { if (pas_is_pedaling_forwards() && (pas_get_pulse_counter() > g_config.pas_start_delay_pulses || speed_sensor_is_moving())) { uint16_t torque_nm_x100 = torque_sensor_get_nm_x100(); uint16_t cadence_rpm_x10 = pas_get_cadence_rpm_x10(); if (cadence_rpm_x10 < TORQUE_POWER_LOWER_RPM_X10) { cadence_rpm_x10 = TORQUE_POWER_LOWER_RPM_X10; } uint16_t pedal_power_w_x10 = (uint16_t)(((uint32_t)torque_nm_x100 * cadence_rpm_x10) / 955); // used in division below to calculate target current, // clamp to 24V if no reading available (unexpected error). uint16_t battery_voltage_x10 = MAX(motor_get_battery_voltage_x10(), 240); uint16_t target_current_amp_x100 = (uint16_t)(((uint32_t)10 * pedal_power_w_x10 * assist_level_data.level.torque_amplification_factor_x10) / battery_voltage_x10); uint16_t max_current_amp_x100 = g_config.max_current_amps * 100; // limit target to ensure no overflow in map result if (target_current_amp_x100 > max_current_amp_x100) { target_current_amp_x100 = max_current_amp_x100; } uint8_t tmp_percent = (uint8_t)MAP32(target_current_amp_x100, 0, max_current_amp_x100, 0, 100); // minimum 1 percent current if pedaling if (tmp_percent < 1) { tmp_percent = 1; } // limit to maximum assist current for set level else if (tmp_percent > assist_level_data.level.target_current_percent) { tmp_percent = assist_level_data.level.target_current_percent; } if (tmp_percent > *target_current) { *target_current = tmp_percent; } } } } #endif void apply_cruise(uint8_t* target_current, uint8_t throttle_percent) { static bool cruise_block_throttle_return = false; if ((assist_level_data.level.flags & ASSIST_FLAG_CRUISE) && throttle_ok()) { // pause cruise if brake activated if (brake_is_activated()) { cruise_paused = true; cruise_block_throttle_return = true; } // pause cruise if started pedaling backwards else if (pas_is_pedaling_backwards() && pas_get_pulse_counter() > CRUISE_DISENGAGE_PAS_PULSES) { cruise_paused = true; cruise_block_throttle_return = true; } // pause cruise if throttle touched while cruise active else if (!cruise_paused && !cruise_block_throttle_return && throttle_percent > 0) { cruise_paused = true; cruise_block_throttle_return = true; } // unpause cruise if pedaling forward while engaging throttle > 50% else if (cruise_paused && !cruise_block_throttle_return && throttle_percent > 50 && pas_is_pedaling_forwards() && pas_get_pulse_counter() > CRUISE_ENGAGE_PAS_PULSES) { cruise_paused = false; cruise_block_throttle_return = true; } // reset flag tracking throttle to make sure throttle returns to idle position before engage/disenage cruise with throttle touch else if (cruise_block_throttle_return && throttle_percent == 0) { cruise_block_throttle_return = false; } if (cruise_paused) { *target_current = 0; } else { if (assist_level_data.level.target_current_percent > *target_current) { *target_current = assist_level_data.level.target_current_percent; } } } } bool apply_throttle(uint8_t* target_current, uint8_t throttle_percent) { if ((assist_level_data.level.flags & ASSIST_FLAG_THROTTLE) && throttle_percent > 0 && throttle_ok()) { uint8_t current = (uint8_t)MAP16(throttle_percent, 0, 100, g_config.throttle_start_percent, assist_level_data.level.max_throttle_current_percent); if (current >= *target_current) { *target_current = current; return true; } } return false; } bool apply_speed_limit(uint8_t* target_current, uint8_t throttle_percent, bool pas_engaged, bool throttle_override) { static bool speed_limiting = false; if (!g_config.use_speed_sensor) { return false; } // global throttle speed limit applies if enabled in configuration, PAS is not engaged and throttle is used bool global_throttle_limit_active = !pas_engaged && throttle_percent > 0 && g_config.throttle_global_spd_lim_percent > 0 && ( g_config.throttle_global_spd_lim_opt == THROTTLE_GLOBAL_SPEED_LIMIT_ENABLED || (g_config.throttle_global_spd_lim_opt == THROTTLE_GLOBAL_SPEED_LIMIT_STD_LVLS && operation_mode == OPERATION_MODE_DEFAULT) ); bool throttle_speed_override_active = !global_throttle_limit_active && throttle_override && (assist_level_data.level.flags & ASSIST_FLAG_PAS) && (assist_level_data.level.flags & ASSIST_FLAG_OVERRIDE_SPEED); int32_t max_speed_rpm_x10; if (global_throttle_limit_active) { // use configured global throttle override speed limit max_speed_rpm_x10 = global_throttle_speed_limit_rpm_x10; } else if (throttle_speed_override_active) { // override assist level speed limit to global speed limit max_speed_rpm_x10 = global_speed_limit_rpm * 10; } else { // normal operation, use configured assist level speed limit max_speed_rpm_x10 = assist_level_data.max_wheel_speed_rpm_x10; } int32_t max_speed_ramp_low_rpm_x10 = max_speed_rpm_x10 - speed_limit_ramp_interval_rpm_x10; int32_t max_speed_ramp_high_rpm_x10 = max_speed_rpm_x10 + speed_limit_ramp_interval_rpm_x10; if (max_speed_rpm_x10 > 0) { int16_t current_speed_rpm_x10 = speed_sensor_get_rpm_x10(); if (current_speed_rpm_x10 < max_speed_ramp_low_rpm_x10) { // no limiting if (speed_limiting) { speed_limiting = false; eventlog_write_data(EVT_DATA_SPEED_LIMITING, 0); } } else { if (!speed_limiting) { speed_limiting = true; eventlog_write_data(EVT_DATA_SPEED_LIMITING, 1); } if (current_speed_rpm_x10 > max_speed_ramp_high_rpm_x10) { if (*target_current > 1) { *target_current = 1; return true; } } else { // linear ramp down when approaching max speed. uint8_t tmp = (uint8_t)MAP32(current_speed_rpm_x10, max_speed_ramp_low_rpm_x10, max_speed_ramp_high_rpm_x10, *target_current, 1); if (*target_current > tmp) { *target_current = tmp; return true; } } } } return false; } bool apply_thermal_limit(uint8_t* target_current) { static uint32_t next_log_temp_ms = 10000; static bool temperature_limiting = false; int16_t temp_contr_x100 = temperature_contr_x100(); temperature_contr_c = temp_contr_x100 / 100; int16_t temp_motor_x100 = temperature_motor_x100(); temperature_motor_c = temp_motor_x100 / 100; int16_t max_temp_x100 = MAX(temp_contr_x100, temp_motor_x100); int8_t max_temp = MAX(temperature_contr_c, temperature_motor_c); if (eventlog_is_enabled() && g_config.use_temperature_sensor && system_ms() > next_log_temp_ms) { next_log_temp_ms = system_ms() + 10000; eventlog_write_data(EVT_DATA_TEMPERATURE, (uint16_t)temperature_motor_c << 8 | temperature_contr_c); } if (max_temp >= (MAX_TEMPERATURE - MAX_TEMPERATURE_RAMP_DOWN_INTERVAL)) { if (!temperature_limiting) { temperature_limiting = true; eventlog_write_data(EVT_DATA_THERMAL_LIMITING, 1); } if (max_temp_x100 > MAX_TEMPERATURE * 100) { max_temp_x100 = MAX_TEMPERATURE * 100; } uint8_t tmp = (uint8_t)MAP32( max_temp_x100, // value (MAX_TEMPERATURE - MAX_TEMPERATURE_RAMP_DOWN_INTERVAL) * 100, // in_min MAX_TEMPERATURE * 100, // in_max 100, // out_min MAX_TEMPERATURE_LOW_CURRENT_PERCENT // out_max ); if (*target_current > tmp) { *target_current = tmp; return true; } } else { if (temperature_limiting) { temperature_limiting = false; eventlog_write_data(EVT_DATA_THERMAL_LIMITING, 0); } } return false; } bool apply_low_voltage_limit(uint8_t* target_current) { static uint32_t next_log_volt_ms = 10000; static bool lvc_limiting = false; static uint32_t next_voltage_reading_ms = 125; static int32_t flt_min_bat_volt_x100 = 100 * 100; if (system_ms() > next_voltage_reading_ms) { next_voltage_reading_ms = system_ms() + 125; int32_t voltage_reading_x100 = motor_get_battery_voltage_x10() * 10ul; if (voltage_reading_x100 < flt_min_bat_volt_x100) { flt_min_bat_volt_x100 = EXPONENTIAL_FILTER(flt_min_bat_volt_x100, voltage_reading_x100, 8); } if (eventlog_is_enabled() && system_ms() > next_log_volt_ms) { next_log_volt_ms = system_ms() + 10000; eventlog_write_data(EVT_DATA_VOLTAGE, (uint16_t)voltage_reading_x100); } } uint16_t voltage_x100 = flt_min_bat_volt_x100; if (voltage_x100 <= lvc_ramp_down_start_voltage_x100) { if (!lvc_limiting) { eventlog_write_data(EVT_DATA_LVC_LIMITING, voltage_x100); lvc_limiting = true; } if (voltage_x100 < lvc_voltage_x100) { voltage_x100 = lvc_voltage_x100; } // Ramp down power until LVC_LOW_CURRENT_PERCENT when approaching LVC uint8_t tmp = (uint8_t)MAP32( voltage_x100, // value lvc_ramp_down_end_voltage_x100, // in_min lvc_ramp_down_start_voltage_x100, // in_max LVC_LOW_CURRENT_PERCENT, // out_min 100 // out_max ); if (*target_current > tmp) { *target_current = tmp; return true; } } return false; } #if HAS_SHIFT_SENSOR_SUPPORT bool apply_shift_sensor_interrupt(uint8_t* target_current) { static uint32_t shift_sensor_act_ms = 0; static bool shift_sensor_last = false; static bool shift_sensor_interrupting = false; static bool shift_sensor_logged = false; // Exit immediately if shift interrupts disabled. if (!g_config.use_shift_sensor) { return false; } bool active = shift_sensor_is_activated(); if (active) { // Check for new pulse from the gear sensor during shift interrupt if (!shift_sensor_last && shift_sensor_interrupting) { // Consecutive gear change, do restart. shift_sensor_interrupting = false; } if (!shift_sensor_interrupting) { uint16_t duration_ms = EXPAND_U16( g_config.shift_interrupt_duration_ms_u16h, g_config.shift_interrupt_duration_ms_u16l ); shift_sensor_act_ms = system_ms() + duration_ms; shift_sensor_interrupting = true; } shift_sensor_last = true; } else { shift_sensor_last = false; } if (!shift_sensor_interrupting) { return false; } if (system_ms() >= shift_sensor_act_ms) { // Shift is finished, reset function state. shift_sensor_interrupting = false; // Logging is skipped, unless current has been clamped during shift interrupt. if (shift_sensor_logged) { shift_sensor_logged = false; eventlog_write_data(EVT_DATA_SHIFT_SENSOR, 0); } return false; } if ((*target_current) > g_config.shift_interrupt_current_threshold_percent) { if (!shift_sensor_logged) { // Logging only once per shifting interrupt. shift_sensor_logged = true; eventlog_write_data(EVT_DATA_SHIFT_SENSOR, 1); } // Set target current based on desired current threshold during shift. *target_current = g_config.shift_interrupt_current_threshold_percent; return true; } return false; } #endif bool apply_brake(uint8_t* target_current) { bool is_braking = brake_is_activated(); if (g_config.lights_mode == LIGHTS_MODE_BRAKE_LIGHT) { lights_set(is_braking); } if (is_braking) { *target_current = 0; } return is_braking; } void apply_current_ramp_up(uint8_t* target_current, bool enable) { static uint8_t ramp_up_target_current = 0; static uint32_t last_ramp_up_increment_ms = 0; if (enable && *target_current > ramp_up_target_current) { uint32_t now = system_ms(); uint16_t time_diff = now - last_ramp_up_increment_ms; if (time_diff >= ramp_up_current_interval_ms) { ++ramp_up_target_current; if (last_ramp_up_increment_ms == 0) { last_ramp_up_increment_ms = now; } else { // offset for time overshoot to not accumulate large ramp error last_ramp_up_increment_ms = now - (uint8_t)(time_diff - ramp_up_current_interval_ms); } } *target_current = ramp_up_target_current; } else { ramp_up_target_current = *target_current; last_ramp_up_increment_ms = 0; } } void apply_current_ramp_down(uint8_t* target_current, bool enable) { static uint8_t ramp_down_target_current = 0; static uint32_t last_ramp_down_decrement_ms = 0; // apply fast ramp down if coming from high target current (> 50%) if (enable && *target_current < ramp_down_target_current) { uint32_t now = system_ms(); uint16_t time_diff = now - last_ramp_down_decrement_ms; if (time_diff >= 10) { uint8_t diff = ramp_down_target_current - *target_current; if (diff >= CURRENT_RAMP_DOWN_PERCENT_10MS) { ramp_down_target_current -= CURRENT_RAMP_DOWN_PERCENT_10MS; } else { ramp_down_target_current -= diff; } if (last_ramp_down_decrement_ms == 0) { last_ramp_down_decrement_ms = now; } else { // offset for time overshoot to not accumulate large ramp error last_ramp_down_decrement_ms = now - (uint8_t)(time_diff - 10); } } *target_current = ramp_down_target_current; } else { ramp_down_target_current = *target_current; last_ramp_down_decrement_ms = 0; } } bool check_power_block() { if (power_blocked_until_ms != 0) { // power block is active, check if time to release if (system_ms() > power_blocked_until_ms) { power_blocked_until_ms = 0; return false; } return true; } return false; } void block_power_for(uint16_t ms) { power_blocked_until_ms = system_ms() + ms; } void reload_assist_params() { if (assist_level < ASSIST_PUSH) { assist_level_data.level = g_config.assist_levels[operation_mode][assist_level]; assist_level_data.max_wheel_speed_rpm_x10 = ((int32_t)global_speed_limit_rpm * assist_level_data.level.max_speed_percent) / 10; if (assist_level_data.level.flags & ASSIST_FLAG_PAS) { assist_level_data.keep_current_target_percent = (uint8_t)((uint16_t)g_config.pas_keep_current_percent * assist_level_data.level.target_current_percent / 100); assist_level_data.keep_current_ramp_start_rpm_x10 = g_config.pas_keep_current_cadence_rpm * 10; assist_level_data.keep_current_ramp_end_rpm_x10 = (uint16_t)(((uint32_t)assist_level_data.level.max_cadence_percent * MAX_CADENCE_RPM_X10) / 100); } // pause cruise if swiching level cruise_paused = true; } // only apply push walk params if push walk is active in config, // otherwise data of previous assist level is kept. else if (assist_level == ASSIST_PUSH && g_config.use_push_walk) { assist_level_data.level.flags = 0; assist_level_data.level.target_current_percent = 0; assist_level_data.level.max_speed_percent = 0; assist_level_data.level.max_cadence_percent = 15; assist_level_data.level.max_throttle_current_percent = 0; assist_level_data.max_wheel_speed_rpm_x10 = convert_wheel_speed_kph_to_rpm(WALK_MODE_SPEED_KPH) * 10; } } uint16_t convert_wheel_speed_kph_to_rpm(uint8_t speed_kph) { float radius_mm = EXPAND_U16(g_config.wheel_size_inch_x10_u16h, g_config.wheel_size_inch_x10_u16l) * 1.27f; // g_config.wheel_size_inch_x10 / 2.f * 2.54f; return (uint16_t)(25000.f / (3 * 3.14159f * radius_mm) * speed_kph); } ================================================ FILE: src/firmware/app.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _APP_H_ #define _APP_H_ #include "intellisense.h" #include #include #define ASSIST_0 0x00 #define ASSIST_1 0x01 #define ASSIST_2 0x02 #define ASSIST_3 0x03 #define ASSIST_4 0x04 #define ASSIST_5 0x05 #define ASSIST_6 0x06 #define ASSIST_7 0x07 #define ASSIST_8 0x08 #define ASSIST_9 0x09 #define ASSIST_PUSH 0x0A #define OPERATION_MODE_DEFAULT 0x00 #define OPERATION_MODE_SPORT 0x01 // Matches status codes used by Bafang #define STATUS_NORMAL 0x01 #define STATUS_BRAKING 0x03 #define STATUS_ERROR_THROTTLE_HIGH 0x04 #define STATUS_ERROR_THROTTLE 0x05 #define STATUS_ERROR_LVC 0x06 #define STATUS_ERROR_HIGH_VOLTAGE 0x07 // not implemented #define STATUS_ERROR_HALL_SENSOR 0x08 #define STATUS_ERROR_PHASE_LINE 0x09 #define STATUS_ERROR_CONTROLLER_OVER_TEMP 0x10 #define STATUS_ERROR_MOTOR_OVER_TEMP 0x11 #define STATUS_ERROR_CURRENT_SENSE 0x12 #define STATUS_ERROR_BATTERY_TEMP_SENSOR 0x13 // n/a #define STATUS_ERROR_MOTOR_TEMP_SENSOR 0x14 // not implemented #define STATUS_ERROR_CONTROLLER_TEMP_SENSOR 0x15 // not implemented #define STATUS_ERROR_SPEED_SENSOR 0x21 // not implemented #define STATUS_ERROR_BMS_COMMUNICATION 0x22 // n/a #define STATUS_ERROR_HEAD_LIGHT 0x23 // not implemented #define STATUS_ERROR_HEAD_LIGHT_SENSOR 0x24 // not implemented #define STATUS_ERROR_TORQUE_SENSOR 0x25 #define STATUS_ERROR_TORQUE_SPEED 0x26 // n/a #define STATUS_ERROR_COMMUNICATION 0x30 // n/a void app_init(); void app_process(); void app_set_assist_level(uint8_t level); void app_set_lights(bool on); void app_set_operation_mode(uint8_t mode); void app_set_wheel_max_speed_rpm(uint16_t value); uint8_t app_get_assist_level(); uint8_t app_get_lights(); uint8_t app_get_status_code(); uint8_t app_get_temperature(); #endif ================================================ FILE: src/firmware/battery.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "battery.h" #include "motor.h" #include "system.h" #include "util.h" #include "cfgstore.h" #include "fwconfig.h" static int16_t battery_empty_x100v; static int16_t battery_full_x100v; static uint8_t battery_percent; static uint32_t motor_disabled_at_ms; static bool first_reading_done; /* No attempt is made to have accurate battery state of charge display. This is only a voltage based approch using configured max and min battery voltages. The end values are padded 8% on each side (BATTERY_EMPTY_OFFSET_PERCENT, BATTERY_FULL_OFFSET_PERCENT). Battery voltage is measured when no motor power has been applied for at least 2 seconds (BATTERY_NO_LOAD_DELAY_MS). This is to mitigate measuring voltage sag but is still problematic in cold weather. Battery SOC percentage is calculated from measured voltage using linear interpolation between the padded ranges. The LVC rampdown starts at 10% battery SOC (LVC_RAMP_DOWN_OFFSET_PERCENT) and will linearly ramp the current down to 20% (LVC_LOW_CURRENT_PERCENT) of the maximum configured current. For example, if the maximum battery voltage is 58.8V and the low cutoff voltage is 42V, then: - The full voltage range is 58.8V - 42V = 16.8V - The padding amount is 0.08 * 16.8V = 1.3V - The battery is considered at 100% SOC at 58.8V - 1.3V = 57.5V - The battery is considered at 0% SOC at 42.0V + 1.3V = 43.3V - LVC rampdown will start at 10% SOC, so: 43.3V + 0.1 * (57.5V - 43.3V) = 44.7V - Full LVC limiting will occur at 0% SOC, so: 43.3V */ static uint8_t compute_battery_percent() { int16_t value_x100v = motor_get_battery_voltage_x10() * 10l; int16_t percent = (int16_t)MAP32(value_x100v, battery_empty_x100v, battery_full_x100v, 0, 100); return (uint8_t)CLAMP(percent, 0, 100); } #if (BATTERY_PERCENT_MAP == BATTERY_PERCENT_MAP_SW102) static uint8_t map_percent_sw102(uint8_t percent) { // Measured on Display // ----------------------- // 0bar 0-5 // 1bar 5 - 10 // 2bar 10 - 30 // 3bar 31 - 51 // 4bar 52 - 78 // 5bar 78 - 100 if (percent < 5) // 0bar { return 0; } else if (percent < 21) // 1bar { return 7; } else if (percent < 41) // 2bar { return 20; } else if (percent < 61) // 3bar { return 40; } else if (percent < 81) // 4bar { return 60; } else // 5bar { return 100; } } #endif void battery_init() { // default to 70% until first reading is available battery_percent = 70; motor_disabled_at_ms = 0; first_reading_done = false; uint16_t battery_min_voltage_x100v = g_config.low_cut_off_v * 100u; uint16_t battery_max_voltage_x100v = EXPAND_U16(g_config.max_battery_x100v_u16h, g_config.max_battery_x100v_u16l); uint16_t battery_range_x100v = battery_max_voltage_x100v - battery_min_voltage_x100v; battery_full_x100v = battery_max_voltage_x100v - ((BATTERY_FULL_OFFSET_PERCENT * battery_range_x100v) / 100); battery_empty_x100v = battery_min_voltage_x100v + ((BATTERY_EMPTY_OFFSET_PERCENT * battery_range_x100v) / 100); } void battery_process() { if (!first_reading_done) { if (motor_get_battery_voltage_x10() > 0) { battery_percent = compute_battery_percent(); first_reading_done = true; } } else { uint8_t target_current = motor_get_target_current(); if (motor_disabled_at_ms == 0 && target_current == 0) { motor_disabled_at_ms = system_ms(); } else if (target_current > 0) { motor_disabled_at_ms = 0; } if (target_current == 0 && (system_ms() - motor_disabled_at_ms) > BATTERY_NO_LOAD_DELAY_MS) { battery_percent = compute_battery_percent(); } } } uint8_t battery_get_percent() { return battery_percent; } uint8_t battery_get_mapped_percent() { #if (BATTERY_PERCENT_MAP == BATTERY_PERCENT_MAP_SW102) return map_percent_sw102(battery_percent); #else return battery_percent; #endif } ================================================ FILE: src/firmware/battery.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _BATTERY_H_ #define _BATTERY_H_ #include void battery_init(); void battery_process(); uint8_t battery_get_percent(); uint8_t battery_get_mapped_percent(); #endif ================================================ FILE: src/firmware/bbs-fw.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33205.214 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bbs-fw", "bbs-fw.vcxproj", "{1D7732D0-C5BC-4E67-9A24-EFF8000C007D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution BBS02|SDCC = BBS02|SDCC BBSHD|SDCC = BBSHD|SDCC TSDZ2|SDCC = TSDZ2|SDCC EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.BBS02|SDCC.ActiveCfg = BBS02|x64 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.BBS02|SDCC.Build.0 = BBS02|x64 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.BBSHD|SDCC.ActiveCfg = BBSHD|x64 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.BBSHD|SDCC.Build.0 = BBSHD|x64 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.TSDZ2|SDCC.ActiveCfg = TSDZ2|x64 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D}.TSDZ2|SDCC.Build.0 = TSDZ2|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2359A0E3-B5F4-4356-ACB7-0730EF01FF2F} EndGlobalSection EndGlobal ================================================ FILE: src/firmware/bbs-fw.vcxproj ================================================ BBS02 x64 BBSHD x64 TSDZ2 x64 16.0 {1D7732D0-C5BC-4E67-9A24-EFF8000C007D} Win32Proj Makefile true v143 Makefile true v143 Makefile true v143 make all TARGET_CONTROLLER=BBSHD bbs-fw.hex make clean make clean make all TARGET_CONTROLLER=BBSHD BBSHD;$(NMakePreprocessorDefinitions) C:/Program Files/SDCC/include;C:/Program Files/SDCC/include/mcs51;./ $(SolutionDir) build\$(Platform)\$(Configuration)\ make all TARGET_CONTROLLER=TSDZ2 bbs-fw.hex make clean make clean make all TARGET_CONTROLLER=TSDZ2 TSDZ2;$(NMakePreprocessorDefinitions) C:/Program Files/SDCC/include;./ $(SolutionDir) build\$(Platform)\$(Configuration)\ make all TARGET_CONTROLLER=BBS02 bbs-fw.hex make clean make clean make all TARGET_CONTROLLER=BBS02 BBS02;$(NMakePreprocessorDefinitions) C:/Program Files/SDCC/include;C:/Program Files/SDCC/include/mcs51;./ $(SolutionDir) build\$(Platform)\$(Configuration)\ ================================================ FILE: src/firmware/bbs-fw.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {3afcc16a-9b6d-48ec-8c37-3d76d5814243} {0753682d-650f-4c13-a2b2-7a748cc9fdee} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files\bbsx Source Files\bbsx Source Files\bbsx Source Files\bbsx Header Files Source Files\tsdz2 Header Files Source Files\bbsx Source Files\bbsx Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Source Files\tsdz2 Header Files ================================================ FILE: src/firmware/bbsx/adc.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "adc.h" #include "bbsx/stc15.h" #include "bbsx/pins.h" static uint8_t next_channel; static uint8_t no_adc_reading_counter; static uint8_t throttle_value; static uint16_t temperature_contr_value; static uint16_t temperature_motor_value; void adc_init() { // Setup pin voltage as high impedance input even though it is not used SET_PIN_INPUT(PIN_VOLTAGE); // Setup pin throttle as adc input SET_PIN_INPUT(PIN_THROTTLE); SET_PIN_LOW(PIN_THROTTLE); SET_BIT(P1ASF, GET_PIN_NUM(PIN_THROTTLE)); // Setup pin controller temperature pin as adc input SET_PIN_INPUT(PIN_TEMPERATURE_CONTR); SET_PIN_LOW(PIN_TEMPERATURE_CONTR); SET_BIT(P1ASF, GET_PIN_NUM(PIN_TEMPERATURE_CONTR)); #ifdef BBSHD // Setup pin motor temperature pin as adc input SET_PIN_INPUT(PIN_TEMPERATURE_MOTOR); SET_PIN_LOW(PIN_TEMPERATURE_MOTOR); SET_BIT(P1ASF, GET_PIN_NUM(PIN_TEMPERATURE_MOTOR)); #endif ADC_RES = 0; ADC_RESL = 0; // Arrange adc result for 8bit reading CLEAR_BIT(PCON2, 5); ADC_CONTR = (uint8_t)((1 << 7)); no_adc_reading_counter = 0; throttle_value = 0; temperature_contr_value = 0; temperature_motor_value = 0; next_channel = GET_PIN_NUM(PIN_THROTTLE); // throttle is read during init since a valid value must be // needs to be available for fir throttle_process to not mess // up safeguard logic // enable adc power and read throttle ADC_CONTR = (uint8_t)((1 << 7) | (1 << 3) | next_channel); // wait for throttle reading and process while (!IS_BIT_SET(ADC_CONTR, 4)); adc_process(); } void adc_process() { // adc reading available if (IS_BIT_SET(ADC_CONTR, 4)) { no_adc_reading_counter = 0; ADC_CONTR = (uint8_t)((1 << 7)); // Clear ADC_FLAG switch (next_channel) { case GET_PIN_NUM(PIN_THROTTLE): { throttle_value = ADC_RES; next_channel = GET_PIN_NUM(PIN_TEMPERATURE_CONTR); break; } case GET_PIN_NUM(PIN_TEMPERATURE_CONTR): { temperature_contr_value = (((uint16_t)ADC_RES) << 2) | ADC_RESL; #ifdef BBSHD next_channel = GET_PIN_NUM(PIN_TEMPERATURE_MOTOR); #else next_channel = GET_PIN_NUM(PIN_THROTTLE); #endif break; } #ifdef BBSHD case GET_PIN_NUM(PIN_TEMPERATURE_MOTOR): { temperature_motor_value = (((uint16_t)ADC_RES) << 2) | ADC_RESL; next_channel = GET_PIN_NUM(PIN_THROTTLE); break; } #endif } } else if (++no_adc_reading_counter == 0) { // reinitialize adc ADC_RES = 0; ADC_CONTR = (uint8_t)(1 << 7); no_adc_reading_counter = 0; throttle_value = 0; temperature_motor_value = 0; temperature_contr_value = 0; next_channel = GET_PIN_NUM(PIN_THROTTLE); } else { return; } // start next reading ADC_RES = 0; ADC_CONTR = (uint8_t)((1 << 7) | (1 << 3) | next_channel); } uint8_t adc_get_throttle() { return throttle_value; } uint16_t adc_get_torque() { return 0; } uint16_t adc_get_temperature_contr() { return temperature_contr_value; } uint16_t adc_get_temperature_motor() { return temperature_motor_value; } uint16_t adc_get_battery_voltage() { // not implemented, motor MCU sends adc battery voltage value return 0; } ================================================ FILE: src/firmware/bbsx/cpu.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _BBSX_CPU_H_ #define _BBSX_CPU_H_ #define CPU_FREQ 20000000L #endif ================================================ FILE: src/firmware/bbsx/eeprom.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "eeprom.h" #include "bbsx/stc15.h" #define EEPROM_NUM_SECTORS 4 // STC chips has a special area in flash for eeprom. #define EEPROM_STC_ADDRESS_OFFSET 0x0000 // IAP chips have no special area, same area as program // memory and address space is the same. We define the last // four sectors for eeprom usage ourself. #define EEPROM_IAP_ADDRESS_OFFSET 0xEC00 #define IAP_CMD_IDLE 0 #define IAP_CMD_READ 1 #define IAP_CMD_PROGRAM 2 #define IAP_CMD_ERASE 3 #define IAP_ENABLE 0x82 // Wait time, CPU_FREQ < 20MHz static uint16_t address_offset = 0x0000; static uint16_t selected_sector_offset = 0; static void eeprom_begin(uint8_t cmd, int offset) { IAP_CONTR = IAP_ENABLE; IAP_CMD = cmd; uint16_t addr = selected_sector_offset + offset; IAP_ADDRH = addr >> 8; IAP_ADDRL = addr; } static bool eeprom_trigger() { IAP_TRIG = 0x5a; IAP_TRIG = 0xa5; NOP(); return !IS_BIT_SET(IAP_CONTR, 4); } static void eeprom_end() { IAP_CONTR = 0; IAP_CMD = 0; IAP_TRIG = 0; IAP_ADDRH = 0xff; IAP_ADDRL = 0xff; } void eeprom_init() { // Detect if we are running on IAP or STC model dependeing on if // we can read from IAP address offset which is outside eeprom // address space on STC model. address_offset = EEPROM_IAP_ADDRESS_OFFSET; eeprom_select_page(0); if (eeprom_read_byte(0) == -1) { address_offset = EEPROM_STC_ADDRESS_OFFSET; } } bool eeprom_select_page(int page) { if (page >= 0 && page < EEPROM_NUM_SECTORS) { selected_sector_offset = address_offset + page * 512; return true; } return false; } bool eeprom_erase_page() { bool res; eeprom_begin(IAP_CMD_ERASE, 0); res = eeprom_trigger(); eeprom_end(); return res; } int eeprom_read_byte(int offset) { int res = -1; eeprom_begin(IAP_CMD_READ, offset); if (eeprom_trigger()) { res = IAP_DATA; } eeprom_end(); return res; } bool eeprom_write_byte(int offset, uint8_t value) { bool res; eeprom_begin(IAP_CMD_PROGRAM, offset); IAP_DATA = value; res = eeprom_trigger(); eeprom_end(); return res; } bool eeprom_end_write() { return true; } ================================================ FILE: src/firmware/bbsx/interrupt.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _BBSX_INTERRUPT_H_ #define _BBSX_INTERRUPT_H_ #include #include "intellisense.h" #define IRQ_TIMER0 1 #define IRQ_UART1 4 #define IRQ_UART2 8 INTERRUPT_USING(isr_timer0, IRQ_TIMER0, 1); // system.c INTERRUPT_USING(isr_uart1, IRQ_UART1, 3); // uart.c INTERRUPT_USING(isr_uart2, IRQ_UART2, 3); // uart.c #endif ================================================ FILE: src/firmware/bbsx/lights.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "lights.h" #include "bbsx/pins.h" #include "bbsx/stc15.h" void lights_init() { SET_PIN_OUTPUT(PIN_LIGHTS_POWER); SET_PIN_OUTPUT(PIN_LIGHTS); lights_disable(); lights_set(false); } void lights_enable() { // enable signal level is swapped on BBSHD vs BBS02... #if defined(BBSHD) SET_PIN_HIGH(PIN_LIGHTS_POWER); #elif defined(BBS02) SET_PIN_LOW(PIN_LIGHTS_POWER); #endif } void lights_disable() { // enable signal level is swapped on BBSHD vs BBS02... #if defined(BBSHD) SET_PIN_LOW(PIN_LIGHTS_POWER); #elif defined(BBS02) SET_PIN_HIGH(PIN_LIGHTS_POWER); #endif } void lights_set(bool on) { if (on) { SET_PIN_LOW(PIN_LIGHTS); } else { SET_PIN_HIGH(PIN_LIGHTS); } } ================================================ FILE: src/firmware/bbsx/motor.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "motor.h" #include "sensors.h" #include "system.h" #include "eventlog.h" #include "bbsx/uart_motor.h" #include "bbsx/pins.h" #include #define OPCODE_LVC 0x60 #define OPCODE_MAX_CURRENT 0x61 #define OPCODE_TARGET_SPEED 0x63 #define OPCODE_TARGET_CURRENT 0x64 #define OPCODE_HELLO 0x67 #define OPCODE_UNKNOWN1 0x68 #define OPCODE_UNKNOWN2 0x69 #define OPCODE_UNKNOWN3 0x6A #define OPCODE_UNKNOWN4 0x6B #define OPCODE_UNKNOWN5 0x6C #define OPCODE_UNKNOWN5 0x6C #define OPCODE_UNKNOWN6 0x6D #define OPCODE_UNKNOWN7 0x6E #define OPCODE_READ_STATUS 0x40 #define OPCODE_READ_CURRENT 0x41 #define OPCODE_READ_VOLTAGE 0x42 #define READ_TIMEOUT 100 #if defined(BBSHD) #define ADC_STEPS_PER_AMP_X10 69 #define ADC_STEPS_PER_VOLT_X100 1490 // 1460 in orginal firmware #elif defined(BBS02) #define ADC_STEPS_PER_AMP_X10 56 #define ADC_STEPS_PER_VOLT_X100 1510 #endif #define SPEED_STEPS 250 // async om state machine #define COM_STATE_IDLE 0x01 #define COM_STATE_WAIT_RESPONSE 0x02 #define COM_STATE_SET_CURRENT 0x03 #define COM_STATE_SET_SPEED 0x04 #define COM_STATE_READ_STATUS 0x05 #define COM_STATE_READ_CURRENT 0x06 #define COM_STATE_READ_VOLTAGE 0x07 #define MSGBUF_SIZE 8 static uint8_t is_connected; static uint8_t msgbuf[MSGBUF_SIZE]; static bool target_speed_changed; static uint8_t target_speed; static bool target_current_changed; static uint8_t target_current; static uint16_t adc_steps_per_volt_x100; static uint16_t lvc_volt_x10; static uint16_t status_flags; static uint16_t battery_volt_x10; static uint16_t battery_adc_steps; static uint16_t battery_amp_x10; // state machine state static uint8_t com_state; static uint8_t last_sent_opcode; static uint32_t last_request_write_ms; static uint32_t last_status_read_ms; static uint8_t next_status_read_opcode; static uint8_t compute_checksum(uint8_t* msg, uint8_t len); static void send_request(uint8_t opcode, uint16_t data); static void send_request_async(uint8_t opcode, uint16_t data); static int read_response(uint8_t opcode, uint16_t* out_data); static int try_read_response(uint8_t opcode, uint16_t* out_data); static int connect(); static int configure(uint16_t max_current_mA, uint8_t lvc_V); static void process_com_state_machine(); void motor_pre_init() { SET_PIN_OUTPUT(PIN_MOTOR_POWER_ENABLE); SET_PIN_OUTPUT(PIN_MOTOR_CONTROL_ENABLE); SET_PIN_OUTPUT(PIN_MOTOR_EXTRA); SET_PIN_LOW(PIN_MOTOR_POWER_ENABLE); SET_PIN_HIGH(PIN_MOTOR_CONTROL_ENABLE); SET_PIN_HIGH(PIN_MOTOR_EXTRA); } void motor_init(uint16_t max_current_mA, uint8_t lvc_V, int16_t adc_calib_volt_steps_x100) { motor_pre_init(); is_connected = 0; target_speed_changed = false; target_speed = 0; target_current_changed = false; target_current = 0; status_flags = 0; adc_steps_per_volt_x100 = ADC_STEPS_PER_VOLT_X100 + adc_calib_volt_steps_x100; lvc_volt_x10 = (uint16_t)lvc_V * 10; battery_volt_x10 = 0; battery_adc_steps = 0; battery_amp_x10 = 0; com_state = COM_STATE_IDLE; last_sent_opcode = 0; last_request_write_ms = 0; last_status_read_ms = 0; next_status_read_opcode = OPCODE_READ_STATUS; uart_motor_open(4800); // Give other MCU time to power on while (system_ms() < 100); if (connect() && configure(max_current_mA, lvc_V)) { is_connected = 1; eventlog_write(EVT_MSG_MOTOR_INIT_OK); motor_set_target_speed(0); motor_set_target_current(0); target_current_changed = true; target_speed_changed = true; } else { eventlog_write(EVT_ERROR_INIT_MOTOR); } } void motor_process() { if (!is_connected) { return; } process_com_state_machine(); } void motor_enable() { SET_PIN_HIGH(PIN_MOTOR_POWER_ENABLE); } void motor_disable() { if (!brake_is_activated()) { // Brake signal is also connected to motor control MCU. // If we disable motor power here during braking it causes // a small issue where change in target current is not accepted // while in disabled state. This will result in a short power spike // when brake eventually released. SET_PIN_LOW(PIN_MOTOR_POWER_ENABLE); } } uint16_t motor_status() { return status_flags; } uint8_t motor_get_target_speed() { return target_speed; } uint8_t motor_get_target_current() { return target_current; } void motor_set_target_speed(uint8_t percent) { if (percent > 100) { percent = 100; } if (target_speed != percent) { target_speed = percent; target_speed_changed = true; } } void motor_set_target_current(uint8_t percent) { if (percent > 100) { percent = 100; } if (target_current != percent) { target_current = percent; target_current_changed = true; } } int16_t motor_calibrate_battery_voltage(uint16_t actual_voltage_x100) { int16_t diff = 0; if (actual_voltage_x100 != 0) { uint16_t calibrated_adc_steps_volt_x100 = (uint16_t)(((uint32_t)battery_adc_steps * 10000u) / actual_voltage_x100); diff = calibrated_adc_steps_volt_x100 - ADC_STEPS_PER_VOLT_X100; adc_steps_per_volt_x100 = calibrated_adc_steps_volt_x100; } else { // reset calibration if 0 is received adc_steps_per_volt_x100 = ADC_STEPS_PER_VOLT_X100; diff = 0; } eventlog_write_data(EVT_DATA_CALIBRATE_VOLTAGE, adc_steps_per_volt_x100); return diff; } uint16_t motor_get_battery_lvc_x10() { return lvc_volt_x10; } uint16_t motor_get_battery_current_x10() { return battery_amp_x10; } uint16_t motor_get_battery_voltage_x10() { return battery_volt_x10; } static uint8_t compute_checksum(uint8_t* msg, uint8_t len) { uint8_t checksum = 0; for (int i = 0; i < len; ++i) { checksum += *(msg + i); } return checksum; } static void send_request(uint8_t opcode, uint16_t data) { // empty rx buffer while (uart_motor_available()) uart_motor_read(); send_request_async(opcode, data); uart_motor_flush(); } static void send_request_async(uint8_t opcode, uint16_t data) { uint8_t idx = 0; msgbuf[idx++] = 0xaa; // start of message msgbuf[idx++] = opcode; if (opcode == OPCODE_LVC) { msgbuf[idx++] = data >> 8; msgbuf[idx++] = data; } else if (opcode != OPCODE_READ_STATUS && opcode != OPCODE_READ_CURRENT && opcode != OPCODE_READ_VOLTAGE) { msgbuf[idx++] = data; } uint8_t checksum = compute_checksum(msgbuf + 1, idx - 1); msgbuf[idx++] = checksum; for (uint8_t i = 0; i < idx; ++i) { uart_motor_write(msgbuf[i]); } } static int read_response(uint8_t opcode, uint16_t* out_data) { uint32_t end = system_ms() + READ_TIMEOUT; uint8_t len = (opcode == OPCODE_LVC || opcode == OPCODE_READ_STATUS || opcode == OPCODE_READ_VOLTAGE) ? 5 : 4; uint8_t i = 0; while (i < len && system_ms() < end) { if (uart_motor_available()) { msgbuf[i++] = uart_motor_read(); } } if (i == len && msgbuf[1] == opcode) { uint8_t checksum = compute_checksum(&msgbuf[1], (uint8_t)(i - 2)); if (checksum == msgbuf[i - 1]) { if (out_data != 0) { if (opcode == OPCODE_LVC || opcode == OPCODE_READ_STATUS || opcode == OPCODE_READ_VOLTAGE) { *out_data = msgbuf[2] << 8 | msgbuf[3]; } else { *out_data = msgbuf[2]; } } return 1; } return 0; // failed to verify message } // read failure return 0; } static int try_read_response(uint8_t opcode, uint16_t* out_data) { uint8_t len = (opcode == OPCODE_LVC || opcode == OPCODE_READ_STATUS || opcode == OPCODE_READ_VOLTAGE) ? 5 : 4; uint8_t i = 0; while (uart_motor_available() && i < MSGBUF_SIZE) { msgbuf[i++] = uart_motor_read(); } // clear anything that could be left in rxbuffer in case of error. while (uart_motor_available()) uart_motor_read(); if (i < len) { // failed to read entire response return 0; } if (i == len && msgbuf[1] == opcode) { uint8_t checksum = compute_checksum(&msgbuf[1], (uint8_t)(i - 2)); if (checksum == msgbuf[i - 1]) { if (out_data != 0) { if (opcode == OPCODE_LVC || opcode == OPCODE_READ_STATUS || opcode == OPCODE_READ_VOLTAGE) { *out_data = ((uint16_t)msgbuf[2] << 8) | msgbuf[3]; } else { *out_data = msgbuf[2]; } } return 1; } return 0; // failed to verify message } // read failure return 0; } static int connect() { for (int i = 0; i < 10; ++i) { send_request(OPCODE_HELLO, 0x00); if (read_response(OPCODE_HELLO, 0)) { system_delay_ms(4); return 1; } else { system_delay_ms(1000); } } return 0; } static int configure(uint16_t max_current_mA, uint8_t lvc_V) { uint16_t tmp = 0; // This initialization is done exactly as in orginal firmware for BBSHD/BBS02. // The meaning of most parameters is unknown. #if defined (BBSHD) send_request(OPCODE_UNKNOWN1, 0x5a); #elif defined (BBS02) send_request(OPCODE_UNKNOWN1, 0x5f); #else return 0; #endif if (!read_response(OPCODE_UNKNOWN1, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN2, 0x11); if (!read_response(OPCODE_UNKNOWN2, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN3, 0x78); if (!read_response(OPCODE_UNKNOWN3, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN4, 0x64); if (!read_response(OPCODE_UNKNOWN4, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN5, 0x50); if (!read_response(OPCODE_UNKNOWN5, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN6, 0x46); if (!read_response(OPCODE_UNKNOWN6, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_UNKNOWN7, 0x0c); if (!read_response(OPCODE_UNKNOWN7, 0)) { return 0; } system_delay_ms(4); send_request(OPCODE_LVC, (uint32_t)(((uint32_t)lvc_V * adc_steps_per_volt_x100) / 100u)); if (!read_response(OPCODE_LVC, 0)) { return 0; } system_delay_ms(4); tmp = (uint16_t)((max_current_mA * (uint32_t)ADC_STEPS_PER_AMP_X10) / 10000UL); if (tmp > 255) { tmp = 255; } eventlog_write_data(EVT_DATA_MAX_CURRENT_ADC_REQUEST, tmp); send_request(OPCODE_MAX_CURRENT, tmp); if (!read_response(OPCODE_MAX_CURRENT, &tmp)) { return 0; } else { eventlog_write_data(EVT_DATA_MAX_CURRENT_ADC_RESPONSE, tmp); } system_delay_ms(4); return 1; } static void process_com_state_machine_idle() { // Async state machine loop for serial communication with motor control MCU. // // Handles: // * Set target current // * Set target speed // * Read motor status // * Read motor current // * Read battery voltage // // Set target speed/current are prioritzed over status reading (shorter check interval). uint32_t now = system_ms(); // make sure requests have some space between them if (now - last_request_write_ms < 32) { return; } if (target_current_changed) { send_request_async(OPCODE_TARGET_CURRENT, target_current); last_sent_opcode = OPCODE_TARGET_CURRENT; last_request_write_ms = now; com_state = COM_STATE_WAIT_RESPONSE; target_current_changed = false; return; } if (target_speed_changed) { send_request_async(OPCODE_TARGET_SPEED, (uint8_t)(((uint16_t)SPEED_STEPS * target_speed) / 100)); last_sent_opcode = OPCODE_TARGET_SPEED; last_request_write_ms = now; com_state = COM_STATE_WAIT_RESPONSE; target_speed_changed = false; return; } if ((now - last_status_read_ms) > 200) { send_request_async(next_status_read_opcode, 0); last_sent_opcode = next_status_read_opcode; last_request_write_ms = now; com_state = COM_STATE_WAIT_RESPONSE; if (next_status_read_opcode == OPCODE_READ_STATUS) { last_status_read_ms = now; } return; } } static void process_com_state_machine_wait_response() { uint8_t response_length = 0; switch (last_sent_opcode) { case OPCODE_TARGET_CURRENT: case OPCODE_TARGET_SPEED: case OPCODE_READ_CURRENT: response_length = 4; break; case OPCODE_READ_VOLTAGE: case OPCODE_READ_STATUS: response_length = 5; break; } if (uart_motor_available() >= response_length || (system_ms() - last_request_write_ms) > 32) { switch (last_sent_opcode) { case OPCODE_TARGET_CURRENT: com_state = COM_STATE_SET_CURRENT; break; case OPCODE_TARGET_SPEED: com_state = COM_STATE_SET_SPEED; break; case OPCODE_READ_CURRENT: com_state = COM_STATE_READ_CURRENT; break; case OPCODE_READ_VOLTAGE: com_state = COM_STATE_READ_VOLTAGE; break; case OPCODE_READ_STATUS: com_state = COM_STATE_READ_STATUS; break; default: com_state = COM_STATE_IDLE; break; } } } static void process_com_state_machine() { uint16_t data; switch (com_state) { case COM_STATE_IDLE: process_com_state_machine_idle(); break; case COM_STATE_WAIT_RESPONSE: process_com_state_machine_wait_response(); break; case COM_STATE_SET_CURRENT: if (try_read_response(OPCODE_TARGET_CURRENT, &data)) { eventlog_write_data(EVT_DATA_TARGET_CURRENT, data); } else { eventlog_write(EVT_ERROR_CHANGE_TARGET_CURRENT); } com_state = COM_STATE_IDLE; break; case COM_STATE_SET_SPEED: if (try_read_response(OPCODE_TARGET_SPEED, &data)) { eventlog_write_data(EVT_DATA_TARGET_SPEED, (uint8_t)((data * 100) / SPEED_STEPS)); } else { eventlog_write(EVT_ERROR_CHANGE_TARGET_SPEED); } com_state = COM_STATE_IDLE; break; case COM_STATE_READ_STATUS: if (try_read_response(OPCODE_READ_STATUS, &data)) { if (data != status_flags) { status_flags = data; eventlog_write_data(EVT_DATA_MOTOR_STATUS, status_flags); } } else { eventlog_write(EVT_ERROR_READ_MOTOR_STATUS); } next_status_read_opcode = OPCODE_READ_CURRENT; com_state = COM_STATE_IDLE; break; case COM_STATE_READ_CURRENT: if (try_read_response(OPCODE_READ_CURRENT, &data)) { battery_amp_x10 = (data * 100) / ADC_STEPS_PER_AMP_X10; } else { eventlog_write(EVT_ERROR_READ_MOTOR_CURRENT); } next_status_read_opcode = OPCODE_READ_VOLTAGE; com_state = COM_STATE_IDLE; break; case COM_STATE_READ_VOLTAGE: if (try_read_response(OPCODE_READ_VOLTAGE, &data)) { battery_adc_steps = data; battery_volt_x10 = (uint16_t)(((uint32_t)battery_adc_steps * 1000) / adc_steps_per_volt_x100); } else { eventlog_write(EVT_ERROR_READ_MOTOR_VOLTAGE); } next_status_read_opcode = OPCODE_READ_STATUS; com_state = COM_STATE_IDLE; break; } } ================================================ FILE: src/firmware/bbsx/pins.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _PINS_H_ #define _PINS_H_ // PORT, PIN #if defined(BBSHD) #define PIN_MOTOR_POWER_ENABLE 2, 0 #define PIN_MOTOR_CONTROL_ENABLE 2, 1 #define PIN_MOTOR_EXTRA 4, 4 #define PIN_MOTOR_RX 1, 0 #define PIN_MOTOR_TX 1, 1 #define PIN_VOLTAGE 1, 6 #define PIN_TEMPERATURE_CONTR 1, 7 #define PIN_TEMPERATURE_MOTOR 1, 4 #define PIN_PAS1 4, 5 #define PIN_PAS2 4, 6 //#define PIN_HALL_U 5, 0 //#define PIN_HALL_V 3, 4 //#define PIN_HALL_W 0, 6 #define PIN_SPEED_SENSOR 2, 2 #define PIN_BRAKE 2, 4 #define PIN_SHIFT_SENSOR 2, 6 #define PIN_THROTTLE 1, 3 #define PIN_LIGHTS_POWER 2, 3 // P+ #define PIN_LIGHTS 5, 1 // Q #define PIN_EXTERNAL_RX 3, 0 #define PIN_EXTERNAL_TX 3, 1 #elif defined(BBS02) #define PIN_MOTOR_POWER_ENABLE 2, 0 #define PIN_MOTOR_CONTROL_ENABLE 5, 4 #define PIN_MOTOR_EXTRA 5, 5 #define PIN_MOTOR_RX 1, 0 #define PIN_MOTOR_TX 1, 1 #define PIN_VOLTAGE 1, 7 #define PIN_TEMPERATURE_CONTR 1, 2 #define PIN_PAS1 2, 3 #define PIN_PAS2 2, 4 #define PIN_SPEED_SENSOR 2, 6 #define PIN_BRAKE 3, 3 #define PIN_SHIFT_SENSOR 3, 6 #define PIN_THROTTLE 1, 5 #define PIN_LIGHTS_POWER 0, 3 // P+ #define PIN_LIGHTS 0, 2 // Q #define PIN_EXTERNAL_RX 3, 0 #define PIN_EXTERNAL_TX 3, 1 #endif #endif ================================================ FILE: src/firmware/bbsx/sensors.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "sensors.h" #include "system.h" #include "adc.h" #include "util.h" #include "cfgstore.h" #include "eventlog.h" #include "fwconfig.h" #include "bbsx/pins.h" #include "bbsx/stc15.h" #include "bbsx/timers.h" #include #include #include // interrupt runs at 100us interval, see timer0 in timers.c // timer0 is shared between system and sensors modules #define PAS_SENSOR_NUM_SIGNALS PAS_PULSES_REVOLUTION #define PAS_SENSOR_MIN_PULSE_MS_X10 50 // 500rpm limit #define SPEED_SENSOR_MIN_PULSE_MS_X10 500 #define SPEED_SENSOR_TIMEOUT_MS_X10 25000 // Some versions of the BBSHD motor (hall sensor board) // has a PTC thermistor instead of a NTC thermistor. // Using standard PT1000 table. // [R_x100, C_x100] #ifdef BBSHD #define BBSHD_PTC_LUT_SIZE 21 typedef struct { int32_t x; int16_t y; } pt_t; static const pt_t bbshd_ptc_lut[BBSHD_PTC_LUT_SIZE] = { { 92100, -2000 }, { 96090, -1000 }, { 100000, 0000 }, { 103900, 1000 }, { 107790, 2000 }, { 109730, 2500 }, { 111670, 3000 }, { 113610, 3500 }, { 115540, 4000 }, { 117470, 4500 }, { 119400, 5000 }, { 121320, 5500 }, { 123240, 6000 }, { 125160, 6500 }, { 127080, 7000 }, { 128990, 7500 }, { 130900, 8000 }, { 132800, 8500 }, { 134710, 9000 }, { 136610, 9500 }, { 138510, 10000 } }; static bool bbshd_ptc_thermistor; #endif static volatile uint16_t pas_pulse_counter; static volatile bool pas_direction_backward; static volatile uint16_t pas_period_length; // pulse length counted in interrupt frequency (100us) static uint16_t pas_period_counter; static bool pas_prev1; static bool pas_prev2; static uint16_t pas_stop_delay_periods; static volatile uint16_t speed_ticks_period_length; // pulse length counted in interrupt frequency (100us) static uint16_t speed_period_counter; static bool speed_prev_state; static uint8_t speed_ticks_per_rpm; static float thermistor_ntc_calculate_temperature(float R, float invBeta) { const float invT0 = 1.f / 298.15f; float K = 1.f / (invT0 + invBeta * (logf(R / 10000.f))); float C = K - 273.15f; return C; } #ifdef BBSHD static int16_t thermistor_ptc_bbshd_calculate_temperature(int32_t R_x100) { // interpolate in lookup table if (R_x100 < bbshd_ptc_lut[0].x) { // use minimum value return bbshd_ptc_lut[0].y; } else if (R_x100 > bbshd_ptc_lut[BBSHD_PTC_LUT_SIZE - 1].x) { // use maximum value return bbshd_ptc_lut[BBSHD_PTC_LUT_SIZE - 1].y; } uint8_t i = 0; for (i = 0; i < BBSHD_PTC_LUT_SIZE - 1; i++) { if (bbshd_ptc_lut[i + 1].x > R_x100) { break; } } return (uint16_t)MAP32(R_x100, bbshd_ptc_lut[i].x, bbshd_ptc_lut[i + 1].x, bbshd_ptc_lut[i].y, bbshd_ptc_lut[i + 1].y); } #endif void sensors_init() { // will be evaulated when first reading take place #ifdef BBSHD bbshd_ptc_thermistor = false; #endif pas_period_counter = 0; pas_pulse_counter = 0; pas_direction_backward = false; pas_period_length = 0; pas_stop_delay_periods = 1500; speed_period_counter = 0; speed_ticks_period_length = 0; speed_prev_state = false; speed_ticks_per_rpm = 1; // pins do not have external interrupt, use timer0 to evaluate state frequently SET_PIN_INPUT(PIN_PAS1); SET_PIN_INPUT(PIN_PAS2); SET_PIN_INPUT(PIN_SPEED_SENSOR); SET_PIN_QUASI(PIN_BRAKE); // input pullup SET_PIN_QUASI(PIN_SHIFT_SENSOR); // input pullup pas_prev1 = GET_PIN_STATE(PIN_PAS1); pas_prev2 = GET_PIN_STATE(PIN_PAS2); timer0_init_sensors(); } void sensors_process() { } void pas_set_stop_delay(uint16_t delay_ms) { pas_stop_delay_periods = delay_ms * 10; } uint16_t pas_get_cadence_rpm_x10() { uint16_t tmp; ET0 = 0; // disable timer0 interrupts tmp = pas_period_length; ET0 = 1; if (tmp > 0) { return (uint16_t)((6000000ul / PAS_SENSOR_NUM_SIGNALS) / tmp); } else { return 0; } } uint16_t pas_get_pulse_counter() { uint16_t tmp; ET0 = 0; // disable timer0 interrupts tmp = pas_pulse_counter; ET0 = 1; return tmp; } bool pas_is_pedaling_forwards() { uint16_t period_length; uint8_t direction_backward; ET0 = 0; // disable timer0 interrupts period_length = pas_period_length; direction_backward = pas_direction_backward; ET0 = 1; // atomic read operation, no need to disable timer interrupt return period_length > 0 && !direction_backward; } bool pas_is_pedaling_backwards() { uint16_t period_length; uint8_t direction_backward; ET0 = 0; // disable timer0 interrupts period_length = pas_period_length; direction_backward = pas_direction_backward; ET0 = 1; return period_length > 0 && direction_backward; } void speed_sensor_set_signals_per_rpm(uint8_t num_signals) { speed_ticks_per_rpm = num_signals; } bool speed_sensor_is_moving() { uint16_t tmp; ET0 = 0; // disable timer0 interrupts tmp = speed_ticks_period_length; ET0 = 1; return tmp > 0; } uint16_t speed_sensor_get_rpm_x10() { uint16_t tmp; ET0 = 0; // disable timer0 interrupts tmp = speed_ticks_period_length; ET0 = 1; if (tmp > 0) { return 6000000ul / tmp / speed_ticks_per_rpm; } return 0; } uint16_t torque_sensor_get_nm_x100() { return 0; } bool torque_sensor_ok() { return true; } int16_t temperature_contr_x100() { const float R1 = 5100.f; const float invBeta = 1.f / 3600.f; static int32_t adc_contr_x100 = 0; if (g_config.use_temperature_sensor & TEMPERATURE_SENSOR_CONTR) { if (adc_contr_x100 == 0) { adc_contr_x100 = adc_get_temperature_contr() * 100l; } else { adc_contr_x100 = EXPONENTIAL_FILTER(adc_contr_x100, adc_get_temperature_contr() * 100l, 4); } if (adc_contr_x100 != 0) { float R = R1 * ((102300.f / (102300.f - adc_contr_x100)) - 1.f); return (int16_t)(thermistor_ntc_calculate_temperature(R, invBeta) * 100.f + 0.5f); } } return 0; } int16_t temperature_motor_x100() { // Sensor only present in the BBSHD motor #if HAS_MOTOR_TEMP_SENSOR const float R1 = 5100.f; const float invBeta = 1.f / 3990.f; static int32_t adc_motor_x100 = 0; if (g_config.use_temperature_sensor & TEMPERATURE_SENSOR_MOTOR) { bool first = false; if (adc_motor_x100 == 0) { first = true; adc_motor_x100 = adc_get_temperature_motor() * 100l; } else { adc_motor_x100 = EXPONENTIAL_FILTER(adc_motor_x100, adc_get_temperature_motor() * 100l, 4); } if (adc_motor_x100 != 0) { float R = R1 * ((102300.f / (102300.f - adc_motor_x100)) - 1.f); if (first) { if (R > 1500.f) { // not likely to be a 1k ptc thermistor, assume 10k ntc bbshd_ptc_thermistor = false; eventlog_write_data(EVT_DATA_BBSHD_THERMISTOR, 0); } else { bbshd_ptc_thermistor = true; eventlog_write_data(EVT_DATA_BBSHD_THERMISTOR, 1); } } if (bbshd_ptc_thermistor) { return thermistor_ptc_bbshd_calculate_temperature((int32_t)(R * 100.f + 0.5f)); } else { return(int16_t)(thermistor_ntc_calculate_temperature(R, invBeta) * 100.f + 0.5f); } } } #endif return 0; } bool brake_is_activated() { return !GET_PIN_STATE(PIN_BRAKE); } bool shift_sensor_is_activated() { return !GET_PIN_STATE(PIN_SHIFT_SENSOR); } #pragma save #pragma nooverlay // See SDCC manual about function calls in ISR void sensors_timer0_isr() // runs every 100us, see timers.c { // WARNING: // No 16/32 bit or float computations in ISR (multiply/divide/modulo). // Read SDCC compiler manual for more info. // Pas { bool pas1 = GET_PIN_STATE(PIN_PAS1); bool pas2 = GET_PIN_STATE(PIN_PAS2); if (pas1 && !pas_prev1 /* && pas_period_counter > PAS_SENSOR_MIN_PULSE_MS_X10 */) { pas_pulse_counter++; if (pas_direction_backward != pas2) { pas_direction_backward = pas2; // Reset pas pulse counter if pedal direction is changed, // this variable counts the number of pulses since start of pedaling session. pas_pulse_counter = 0; } if (pas_period_counter > 0) { if (pas_period_counter <= pas_stop_delay_periods) { pas_period_length = pas_period_counter; // save in order to be able to calculate rpm when needed } else { pas_period_length = 0; } pas_period_counter = 0; } } else { // Do not allow wraparound or computed pedaling cadence will wrong after pedals has been still. if (pas_period_counter < 65535) { pas_period_counter++; } if (pas_period_length > 0 && pas_period_counter > pas_stop_delay_periods) { pas_period_length = 0; pas_pulse_counter = 0; pas_direction_backward = false; } } pas_prev1 = pas1; pas_prev2 = pas2; } // Speed sensor { bool spd = GET_PIN_STATE(PIN_SPEED_SENSOR); if (spd && !speed_prev_state && speed_period_counter > SPEED_SENSOR_MIN_PULSE_MS_X10) { if (speed_period_counter <= SPEED_SENSOR_TIMEOUT_MS_X10) { speed_ticks_period_length = speed_period_counter; } else { speed_ticks_period_length = 0; } speed_period_counter = 0; } else { // Do not allow wraparound or computed speed will wrong after bike has been still. if (speed_period_counter < 65535) { speed_period_counter++; } if (speed_ticks_period_length > 0 && speed_period_counter > SPEED_SENSOR_TIMEOUT_MS_X10) { speed_ticks_period_length = 0; } } speed_prev_state = spd; } } #pragma restore ================================================ FILE: src/firmware/bbsx/stc15.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _STC_15_H_ #define _STC_15_H_ #include "intellisense.h" #if !defined (SDCC) && !defined (__SDCC) #define __sfr unsigned char #define __sbit bool #define __at(X) #define __xdata #define __data #endif #include <8051.h> #include // Peripheral function switch SFR(P_SW2, 0xBA); SFR(PCON2, 0x97); SFR(T2H, 0xD6); SFR(T2L, 0xD7); SBIT(P5_4, 0xC8, 4); SBIT(P5_5, 0xC8, 5); #define IS_BIT_SET(REG, BIT_NUM) ((REG >> BIT_NUM) & 1) #define SET_BIT(REG, BIT_NUM) (REG |= (1 << BIT_NUM)) #define CLEAR_BIT(REG, BIT_NUM) (REG &= ~(1 << BIT_NUM)) #define TOGGLE_BIT(REG, BIT_NUM) (REG ^= (1 << BIT_NUM)) #define EXPAND(x) x #define SET_PIN_INPUT_(PORT, PIN) CLEAR_BIT(P##PORT##M0, PIN); SET_BIT(P##PORT##M1, PIN) #define SET_PIN_INPUT(...) EXPAND(SET_PIN_INPUT_(__VA_ARGS__)) #define SET_PIN_QUASI_(PORT, PIN) CLEAR_BIT(P##PORT##M0, PIN); CLEAR_BIT(P##PORT##M1, PIN) #define SET_PIN_QUASI(...) EXPAND(SET_PIN_QUASI_(__VA_ARGS__)) #define SET_PIN_OUTPUT_(PORT, PIN) SET_BIT(P##PORT##M0, PIN); CLEAR_BIT(P##PORT##M1, PIN) #define SET_PIN_OUTPUT(...) EXPAND(SET_PIN_OUTPUT_(__VA_ARGS__)) #define GET_PIN_STATE_(PORT, PIN) P##PORT##_##PIN #define GET_PIN_STATE(...) EXPAND(GET_PIN_STATE_(__VA_ARGS__)) #define SET_PIN_HIGH_(PORT, PIN) P##PORT##_##PIN = 1 #define SET_PIN_HIGH(...) EXPAND(SET_PIN_HIGH_(__VA_ARGS__)) #define SET_PIN_LOW_(PORT, PIN) P##PORT##_##PIN = 0 #define SET_PIN_LOW(...) EXPAND(SET_PIN_LOW_(__VA_ARGS__)) #define GET_PIN_NUM_(PORT, PIN) PIN #define GET_PIN_NUM(...) EXPAND(GET_PIN_NUM_(__VA_ARGS__)) #define GET_PORT_NUM_(PORT, PIN) PORT #define GET_PORT_NUM(...) EXPAND(GET_PORT_NUM_(__VA_ARGS__)) #endif ================================================ FILE: src/firmware/bbsx/system.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "system.h" #include "watchdog.h" #include "timers.h" #include "bbsx/stc15.h" static volatile uint32_t _ms; static volatile uint8_t _x100us; void system_init() { _ms = 0; _x100us = 0; // Wait for stable voltage (above lvd) while (IS_BIT_SET(PCON, 5)) { CLEAR_BIT(PCON, 5); } timer0_init_system(); } uint32_t system_ms() { uint32_t val; uint8_t et0 = ET0; ET0 = 0; // disable timer0 interrupts val = _ms; ET0 = et0; return val; } void system_delay_ms(uint16_t ms) { if (!ms) { return; } uint32_t end = system_ms() + ms; while (system_ms() != end) { watchdog_yeild(); } } #pragma save #pragma nooverlay // See SDCC manual about function calls in ISR void system_timer0_isr() { _x100us++; if (_x100us == 10) { _x100us = 0; _ms++; } } #pragma restore ================================================ FILE: src/firmware/bbsx/timers.c ================================================ #include "timers.h" #include "bbsx/timers.h" #include "bbsx/interrupt.h" #include "bbsx/cpu.h" #include #define TIMER0_RELOAD ((65535 - CPU_FREQ / 10000) + 1) extern void system_timer0_isr(); extern void sensors_timer0_isr(); static bool timer0_system_ready; static bool timer0_sensors_ready; static void timer0_init() { if (timer0_system_ready || timer0_sensors_ready) { // already initialized return; } EA = 0; // disable interrupts TMOD = (TMOD & 0xf0) | 0x00; // Timer 0: 16-bit with autoreload AUXR |= 0x80; // Run timer 0 at CPU_FREQ TH0 = TIMER0_RELOAD >> 8; TL0 = TIMER0_RELOAD; EA = 1; // enable interrupts ET0 = 1; // enable timer0 interrupts TR0 = 1; // start timer 0 } void timers_init() { timer0_system_ready = false; timer0_sensors_ready = false; } void timer0_init_system() { timer0_init(); timer0_system_ready = true; } void timer0_init_sensors() { timer0_init(); timer0_sensors_ready = true; } void timer1_init_uart1(uint32_t baudrate) { unsigned short reload = 65535 - CPU_FREQ / 4 / baudrate + 1; // Set up timer 1 for baudrate TMOD = (TMOD & 0x0f) | 0x00; // Run T1 in mode 0 (16-bit reload) AUXR |= 0x40; // Run T1 at CPU_FREQ TL1 = reload; // Set the reload value for given baudrate. TH1 = reload >> 8; ET1 = 0; // No interrupts from timer 1. TR1 = 1; // Start timer 1 } void timer2_init_uart2(uint32_t baudrate) { unsigned short reload = 65535 - CPU_FREQ / 4 / baudrate + 1; // Set up timer 2 for baudrate AUXR &= ~(1 << 3); // as timer AUXR |= (1 << 2); // Run T2 at CPU_FREQ T2H = reload >> 8; T2L = reload; IE2 &= ~(1 << 2); // No interrupts from timer 2 AUXR |= (1 << 4); // Start timer 2 } // timer0 is shared between system ms counter and sensors check INTERRUPT_USING(isr_timer0, IRQ_TIMER0, 1) { if (timer0_system_ready) { system_timer0_isr(); } if (timer0_sensors_ready) { sensors_timer0_isr(); } } ================================================ FILE: src/firmware/bbsx/timers.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _BBSX_TIMER_H_ #define _BBSX_TIMER_H_ #include "bbsx/stc15.h" #include void timer0_init_system(); void timer0_init_sensors(); void timer1_init_uart1(uint32_t baudrate); void timer2_init_uart2(uint32_t baudrate); #endif ================================================ FILE: src/firmware/bbsx/uart.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "uart.h" #include "system.h" #include "watchdog.h" #include "bbsx/stc15.h" #include "bbsx/uart_motor.h" #include "bbsx/timers.h" #include "bbsx/pins.h" #include // NOTE: // Variables located in __data are there for atomic access. // UART1 (main) #define RX1_BUFFER_SIZE 64 #define RX1_BUFFER_MASK (RX1_BUFFER_SIZE - 1) #define TX1_BUFFER_SIZE 32 #define TX1_BUFFER_MASK (TX1_BUFFER_SIZE - 1) static volatile __data uint8_t rx1_head; static volatile __data uint8_t rx1_tail; static volatile uint8_t rx1_buf[RX1_BUFFER_SIZE]; static volatile __data uint8_t tx1_head; static volatile __data uint8_t tx1_tail; static volatile __data uint8_t tx1_sending; static volatile uint8_t tx1_buf[TX1_BUFFER_SIZE]; // UART2 (motor) #define RX2_BUFFER_SIZE 16 #define RX2_BUFFER_MASK (RX2_BUFFER_SIZE - 1) #define TX2_BUFFER_SIZE 16 #define TX2_BUFFER_MASK (TX2_BUFFER_SIZE - 1) static volatile __data uint8_t rx2_head; static volatile __data uint8_t rx2_tail; static volatile uint8_t rx2_buf[RX2_BUFFER_SIZE]; static volatile __data uint8_t tx2_head; static volatile __data uint8_t tx2_tail; static volatile __data uint8_t tx2_sending; static volatile uint8_t tx2_buf[TX2_BUFFER_SIZE]; void uart_open(uint32_t baudrate) { rx1_head = 0; rx1_tail = 0; tx1_head = 0; tx1_tail = 0; tx1_sending = 0; #if (GET_PORT_NUM(PIN_EXTERNAL_RX) == 3 && GET_PORT_NUM(PIN_EXTERNAL_TX) == 3) AUXR1 = (AUXR1 & 0x3f) | 0x00; // Keep UART1 on P3.0/P3.1 #else #error Unupported UART port configured. #endif SET_PIN_QUASI(PIN_EXTERNAL_RX); SET_PIN_QUASI(PIN_EXTERNAL_TX); AUXR &= ~0x01; // Clock UART1 from T1 PCON &= ~0x40; // Expose SM0 bit SM1 = 1; // UART 8-N-1 SM0 = 0; SM2 = 0; // Point-to-point UART ES = 1; // Enable serial interrupt timer1_init_uart1(baudrate); REN = 1; // Rx enable } void uart_motor_open(uint32_t baudrate) { rx2_head = 0; rx2_tail = 0; tx2_head = 0; tx2_tail = 0; tx2_sending = 0; #if (GET_PORT_NUM(PIN_MOTOR_RX) == 1 && GET_PORT_NUM(PIN_MOTOR_TX) == 1) { P_SW2 = (P_SW2 & 0xfe) | 0x00; // Keep UART2 on P1.0/P1.1 } #else #error Unupported UART port configured. #endif SET_PIN_QUASI(PIN_MOTOR_RX); SET_PIN_QUASI(PIN_MOTOR_TX); // UART 2 can only user timer 2 S2CON &= ~(1 << 7); // UART 8-N-1 S2CON &= ~(1 << 5); // Point-to-point UART IE2 |= (1 << 0); // Enable serial 2 interrupt timer2_init_uart2(baudrate); S2CON |= (1 << 4); // Rx enable } void uart_close() { REN = 0; uart_flush(); TR1 = 0; } void uart_motor_close() { S2CON &= ~(1 << 4); // Rx disable uart_motor_flush(); AUXR &= ~(1 << 4); // Stop timer 2 } uint8_t uart_available() { return (RX1_BUFFER_SIZE + rx1_head - rx1_tail) & RX1_BUFFER_MASK; } uint8_t uart_motor_available() { return (RX2_BUFFER_SIZE + rx2_head - rx2_tail) & RX2_BUFFER_MASK; } uint8_t uart_read() { uint8_t byte = rx1_buf[rx1_tail]; rx1_tail = (rx1_tail + 1) & RX1_BUFFER_MASK; return byte; } uint8_t uart_motor_read() { uint8_t byte = rx2_buf[rx2_tail]; rx2_tail = (rx2_tail + 1) & RX2_BUFFER_MASK; return byte; } void uart_write(uint8_t byte) { if (!tx1_sending) { tx1_sending = 1; SBUF = byte; return; } uint8_t i = (tx1_head + 1) & TX1_BUFFER_MASK; // wait for free space in buffer uint8_t prev_tail = tx1_tail; while (i == tx1_tail) { if (tx1_tail != prev_tail) { prev_tail = tx1_tail; watchdog_yeild(); } } tx1_buf[tx1_head] = byte; tx1_head = i; } void uart_motor_write(uint8_t byte) { if (!tx2_sending) { tx2_sending = 1; S2BUF = byte; return; } uint8_t i = (tx2_head + 1) & TX2_BUFFER_MASK; // wait for free space in buffer uint8_t prev_tail = tx2_tail; while (i == tx2_tail) { if (tx2_tail != prev_tail) { prev_tail = tx2_tail; watchdog_yeild(); } } tx2_buf[tx2_head] = byte; tx2_head = i; } void uart_flush() { while (tx1_sending); } void uart_motor_flush() { while (tx2_sending); } INTERRUPT_USING(isr_uart1, IRQ_UART1, 3) { if (RI) // rx interrupt { RI = 0; uint8_t c = SBUF; uint8_t i = (rx1_head + 1) & RX1_BUFFER_MASK; if (i != rx1_tail) { rx1_buf[rx1_head] = c; rx1_head = i; } } if (TI) // tx interrupt { TI = 0; if (tx1_head != tx1_tail) { tx1_sending = 1; SBUF = tx1_buf[tx1_tail]; tx1_tail = (tx1_tail + 1) & TX1_BUFFER_MASK; } else { tx1_sending = 0; } } } INTERRUPT_USING(isr_uart2, IRQ_UART2, 3) { if (S2CON & (1 << 0)) // rx interrupt { S2CON &= ~(1 << 0); uint8_t c = S2BUF; uint8_t i = (rx2_head + 1) & RX2_BUFFER_MASK; if (i != rx2_tail) { rx2_buf[rx2_head] = c; rx2_head = i; } } if (S2CON & (1 << 1)) // tx interrupt { S2CON &= ~(1 << 1); if (tx2_head != tx2_tail) { tx2_sending = 1; S2BUF = tx2_buf[tx2_tail]; tx2_tail = (tx2_tail + 1) & TX2_BUFFER_MASK; } else { tx2_sending = 0; } } } ================================================ FILE: src/firmware/bbsx/uart_motor.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _BBSX_UART_MOTOR_H_ #define _BBSX_UART_MOTOR_H_ #include "bbsx/stc15.h" #include "bbsx/interrupt.h" #include void uart_motor_open(uint32_t baudrate); void uart_motor_close(); uint8_t uart_motor_available(); uint8_t uart_motor_read(); void uart_motor_write(uint8_t byte); void uart_motor_flush(); #endif ================================================ FILE: src/firmware/bbsx/watchdog.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "watchdog.h" #include "bbsx/stc15.h" static bool triggered; void watchdog_init() { triggered = IS_BIT_SET(WDT_CONTR, 7); WDT_CONTR = 0x34; // Enable watchdog timer, pre-scaler 32 (625ms, 20MHz) } void watchdog_yeild() { SET_BIT(WDT_CONTR, 4); } bool watchdog_triggered() { return triggered; } ================================================ FILE: src/firmware/cfgstore.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "cfgstore.h" #include "eeprom.h" #include "eventlog.h" #include "uart.h" #include "fwconfig.h" #include #define EEPROM_CONFIG_PAGE 0 #define EEPROM_PSTATE_PAGE 1 #define EEPROM_OK 0 #define EEPROM_ERROR_SELECT_PAGE 1 #define EEPROM_ERROR_READ 2 #define EEPROM_ERROR_VERSION 3 #define EEPROM_ERROR_LENGHT 4 #define EEPROM_ERROR_CHECKSUM 5 #define EEPROM_ERROR_ERASE 6 #define EEPROM_ERROR_WRITE 7 static const uint8_t default_current_limits[] = { 7, 10, 14, 19, 26, 36, 50, 70, 98 }; #if HAS_TORQUE_SENSOR static const uint8_t default_torque_factors[] = { 10, 15, 23, 44, 57, 74, 88, 105, 126 }; #endif typedef struct { uint8_t version; uint8_t length; uint8_t checksum; } header_t; static header_t header; config_t g_config; pstate_t g_pstate; static uint8_t read(uint8_t page, uint8_t version, uint8_t* dst, uint8_t size); static uint8_t write(uint8_t page, uint8_t version, uint8_t* src, uint8_t size); static bool read_config(); static bool write_config(); static void load_default_config(); static bool read_pstate(); static bool write_pstate(); static void load_default_pstate(); void cfgstore_init() { if (!read_config()) { cfgstore_reset_config(); } if (!read_pstate()) { cfgstore_reset_pstate(); } } bool cfgstore_reset_config() { load_default_config(); if (write_config()) { eventlog_write(EVT_MSG_CONFIG_RESET); return true; } return false; } bool cfgstore_save_config() { return write_config(); } bool cfgstore_reset_pstate() { load_default_pstate(); return write_pstate(); } bool cfgstore_save_pstate() { return write_pstate(); } static bool read_config() { eventlog_write(EVT_MSG_CONFIG_READ_BEGIN); uint8_t res = read(EEPROM_CONFIG_PAGE, CONFIG_VERSION, (uint8_t*)&g_config, sizeof(config_t)); switch (res) { default: eventlog_write(EVT_ERROR_EEPROM_READ); break; case EEPROM_ERROR_VERSION: eventlog_write(EVT_ERROR_EEPROM_VERIFY_VERSION); break; case EEPROM_ERROR_LENGHT: case EEPROM_ERROR_CHECKSUM: eventlog_write(EVT_ERROR_EEPROM_VERIFY_CHECKSUM); break; case EEPROM_OK: eventlog_write(EVT_MSG_CONFIG_READ_DONE); break; } return res == EEPROM_OK; } static bool write_config() { eventlog_write(EVT_MSG_CONFIG_WRITE_BEGIN); uint8_t res = write(EEPROM_CONFIG_PAGE, CONFIG_VERSION, (uint8_t*)&g_config, sizeof(config_t)); switch (res) { default: eventlog_write(EVT_ERROR_EEPROM_WRITE); break; case EEPROM_ERROR_ERASE: eventlog_write(EVT_ERROR_EEPROM_ERASE); break; case EEPROM_OK: eventlog_write(EVT_MSG_CONFIG_WRITE_DONE); break; } return res == EEPROM_OK; } static void load_default_config() { g_config.use_freedom_units = 0; #if defined(BBSHD) g_config.max_current_amps = 30; #elif defined(BBS02) g_config.max_current_amps = 25; #else g_config.max_current_amps = 20; #endif g_config.current_ramp_amps_s = 10; g_config.max_battery_x100v_u16l = (uint8_t)5460; g_config.max_battery_x100v_u16h = (uint8_t)(5460 >> 8); g_config.low_cut_off_v = 42; g_config.use_speed_sensor = 1; g_config.use_shift_sensor = HAS_SHIFT_SENSOR_SUPPORT; g_config.use_push_walk = 1; g_config.use_pretension = 0; g_config.pretension_speed_cutoff_kph = 16; g_config.use_temperature_sensor = TEMPERATURE_SENSOR_CONTR | TEMPERATURE_SENSOR_MOTOR; g_config.lights_mode = LIGHTS_MODE_DEFAULT; g_config.wheel_size_inch_x10_u16l = (uint8_t)280; g_config.wheel_size_inch_x10_u16h = (uint8_t)(280 >> 8); g_config.speed_sensor_signals = 1; g_config.max_speed_kph = 100; g_config.pas_start_delay_pulses = 5; g_config.pas_stop_delay_x100s = 20; g_config.pas_keep_current_percent = 60; g_config.pas_keep_current_cadence_rpm = 40; g_config.throttle_start_voltage_mv_u16l = (uint8_t)1000; g_config.throttle_start_voltage_mv_u16h = (uint8_t)(1000 >> 8); g_config.throttle_end_voltage_mv_u16l = (uint8_t)3600; g_config.throttle_end_voltage_mv_u16h = (uint8_t)(3600 >> 8); g_config.throttle_start_percent = 1; g_config.throttle_global_spd_lim_opt = THROTTLE_GLOBAL_SPEED_LIMIT_DISABLED; g_config.throttle_global_spd_lim_percent = 100; g_config.shift_interrupt_duration_ms_u16l = (uint8_t)600; g_config.shift_interrupt_duration_ms_u16h = (uint8_t)(600 >> 8); g_config.shift_interrupt_current_threshold_percent = 10; g_config.walk_mode_data_display = WALK_MODE_DATA_SPEED; g_config.assist_mode_select = ASSIST_MODE_SELECT_OFF; g_config.assist_startup_level = 3; memset(&g_config.assist_levels, 0, 20 * sizeof(assist_level_t)); for (uint8_t i = 0; i < 9; ++i) { g_config.assist_levels[0][i+1].flags = ASSIST_FLAG_PAS | ASSIST_FLAG_THROTTLE; g_config.assist_levels[0][i+1].max_cadence_percent = 100; g_config.assist_levels[0][i+1].max_speed_percent = 100; g_config.assist_levels[0][i+1].max_throttle_current_percent = 100; #if HAS_TORQUE_SENSOR g_config.assist_levels[0][i+1].flags |= ASSIST_FLAG_PAS_TORQUE; g_config.assist_levels[0][i+1].target_current_percent = 100; g_config.assist_levels[0][i+1].torque_amplification_factor_x10 = default_torque_factors[i]; #else g_config.assist_levels[0][i+1].target_current_percent = default_current_limits[i]; g_config.assist_levels[0][i+1].torque_amplification_factor_x10 = 0; #endif } } static bool read_pstate() { eventlog_write(EVT_MSG_PSTATE_READ_BEGIN); uint8_t res = read(EEPROM_PSTATE_PAGE, PSTATE_VERSION, (uint8_t*)&g_pstate, sizeof(pstate_t)); switch (res) { default: eventlog_write(EVT_ERROR_EEPROM_READ); break; case EEPROM_ERROR_VERSION: eventlog_write(EVT_ERROR_EEPROM_VERIFY_VERSION); break; case EEPROM_ERROR_LENGHT: case EEPROM_ERROR_CHECKSUM: eventlog_write(EVT_ERROR_EEPROM_VERIFY_CHECKSUM); break; case EEPROM_OK: eventlog_write(EVT_MSG_PSTATE_READ_DONE); break; } return res == EEPROM_OK; } static bool write_pstate() { eventlog_write(EVT_MSG_PSTATE_WRITE_BEGIN); uint8_t res = write(EEPROM_PSTATE_PAGE, PSTATE_VERSION, (uint8_t*)&g_pstate, sizeof(pstate_t)); switch (res) { default: eventlog_write(EVT_ERROR_EEPROM_WRITE); break; case EEPROM_ERROR_ERASE: eventlog_write(EVT_ERROR_EEPROM_ERASE); break; case EEPROM_OK: eventlog_write(EVT_MSG_PSTATE_WRITE_DONE); break; } return res == EEPROM_OK; } static void load_default_pstate() { g_pstate.adc_voltage_calibration_steps_x100_i16l = 0; g_pstate.adc_voltage_calibration_steps_x100_i16h = 0; } static uint8_t read(uint8_t page, uint8_t version, uint8_t* dst, uint8_t size) { uint8_t read_offset = 0; uint8_t* ptr = 0; uint8_t i = 0; int data; if (!eeprom_select_page(page)) { return EEPROM_ERROR_SELECT_PAGE; } ptr = (uint8_t*)&header; for (i = 0; i < sizeof(header_t); ++i) { data = eeprom_read_byte(read_offset); if (data < 0) { return EEPROM_ERROR_READ; } *ptr = (uint8_t)data; ++read_offset; ++ptr; } // verify header ok if (header.version != version) { return EEPROM_ERROR_VERSION; } if (header.length != size) { return EEPROM_ERROR_LENGHT; } uint8_t checksum = 0; ptr = dst; for (i = 0; i < size; ++i) { data = eeprom_read_byte(read_offset); if (data < 0) { return EEPROM_ERROR_READ; } checksum += (uint8_t)data; *ptr = (uint8_t)data; ++read_offset; ++ptr; } if (header.checksum != checksum) { return EEPROM_ERROR_CHECKSUM; } return EEPROM_OK; } static uint8_t write(uint8_t page, uint8_t version, uint8_t* src, uint8_t size) { uint8_t write_offset = 0; uint8_t* ptr = 0; uint8_t i = 0; header.version = version; header.length = size; header.checksum = 0; if (!eeprom_select_page(page)) { return EEPROM_ERROR_SELECT_PAGE; } if (!eeprom_erase_page()) { return EEPROM_ERROR_ERASE; } write_offset += sizeof(header_t); ptr = src; for (i = 0; i < size; ++i) { if (!eeprom_write_byte(write_offset, *ptr)) { eeprom_end_write(); return EEPROM_ERROR_WRITE; } header.checksum += *ptr; ++write_offset; ++ptr; } write_offset = 0; ptr = (uint8_t*)&header; for (i = 0; i < sizeof(header_t); ++i) { if (!eeprom_write_byte(write_offset, *ptr)) { eeprom_end_write(); return EEPROM_ERROR_WRITE; } ++write_offset; ++ptr; } eeprom_end_write(); return EEPROM_OK; } ================================================ FILE: src/firmware/cfgstore.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _CFGSTORE_H_ #define _CFGSTORE_H_ #include "intellisense.h" #include #include #define ASSIST_FLAG_PAS 0x01 #define ASSIST_FLAG_THROTTLE 0x02 #define ASSIST_FLAG_CRUISE 0x04 #define ASSIST_FLAG_PAS_VARIABLE 0x08 // pas mode using throttle to set power level #define ASSIST_FLAG_PAS_TORQUE 0x10 // pas mode using torque sensor reading #define ASSIST_FLAG_OVERRIDE_CADENCE 0x20 // pas option where max cadence is set to 100% when throttle overrides pas #define ASSIST_FLAG_OVERRIDE_SPEED 0x40 // pas option where max speed is set to 100% when throttle overrides pas #define ASSIST_MODE_SELECT_OFF 0x00 #define ASSIST_MODE_SELECT_STANDARD 0x01 #define ASSIST_MODE_SELECT_LIGHTS 0x02 #define ASSIST_MODE_SELECT_PAS0_LIGHT 0x03 #define ASSIST_MODE_SELECT_PAS1_LIGHT 0x04 #define ASSIST_MODE_SELECT_PAS2_LIGHT 0x05 #define ASSIST_MODE_SELECT_PAS3_LIGHT 0x06 #define ASSIST_MODE_SELECT_PAS4_LIGHT 0x07 #define ASSIST_MODE_SELECT_PAS5_LIGHT 0x08 #define ASSIST_MODE_SELECT_PAS6_LIGHT 0x09 #define ASSIST_MODE_SELECT_PAS7_LIGHT 0x0A #define ASSIST_MODE_SELECT_PAS8_LIGHT 0x0B #define ASSIST_MODE_SELECT_PAS9_LIGHT 0x0C #define ASSIST_MODE_SELECT_BRAKE_BOOT 0x0D #define TEMPERATURE_SENSOR_CONTR 0x01 #define TEMPERATURE_SENSOR_MOTOR 0x02 #define WALK_MODE_DATA_SPEED 0 #define WALK_MODE_DATA_TEMPERATURE 1 #define WALK_MODE_DATA_REQUESTED_POWER 2 #define WALK_MODE_DATA_BATTERY_PERCENT 3 #define THROTTLE_GLOBAL_SPEED_LIMIT_DISABLED 0 #define THROTTLE_GLOBAL_SPEED_LIMIT_ENABLED 1 #define THROTTLE_GLOBAL_SPEED_LIMIT_STD_LVLS 2 #define LIGHTS_MODE_DEFAULT 0 #define LIGHTS_MODE_DISABLED 1 #define LIGHTS_MODE_ALWAYS_ON 2 #define LIGHTS_MODE_BRAKE_LIGHT 3 #define CONFIG_VERSION 5 #define PSTATE_VERSION 1 typedef struct { uint8_t flags; uint8_t target_current_percent; uint8_t max_throttle_current_percent; uint8_t max_cadence_percent; uint8_t max_speed_percent; // 10 => 1.0: 100w human power gives and additional 100w motor power uint8_t torque_amplification_factor_x10; } assist_level_t; // SDCC uses little endian for MCS51 and big endian for STM8... typedef struct { // hmi units uint8_t use_freedom_units; // global uint8_t max_current_amps; uint8_t current_ramp_amps_s; uint8_t max_battery_x100v_u16l; uint8_t max_battery_x100v_u16h; uint8_t low_cut_off_v; uint8_t max_speed_kph; // externals uint8_t use_speed_sensor; uint8_t use_shift_sensor; uint8_t use_push_walk; uint8_t use_temperature_sensor; uint8_t lights_mode; uint8_t use_pretension; uint8_t pretension_speed_cutoff_kph; // speed sensor uint8_t wheel_size_inch_x10_u16l; uint8_t wheel_size_inch_x10_u16h; uint8_t speed_sensor_signals; // pas options uint8_t pas_start_delay_pulses; uint8_t pas_stop_delay_x100s; uint8_t pas_keep_current_percent; uint8_t pas_keep_current_cadence_rpm; // throttle options uint8_t throttle_start_voltage_mv_u16l; uint8_t throttle_start_voltage_mv_u16h; uint8_t throttle_end_voltage_mv_u16l; uint8_t throttle_end_voltage_mv_u16h; uint8_t throttle_start_percent; uint8_t throttle_global_spd_lim_opt; uint8_t throttle_global_spd_lim_percent; // shift interrupt options uint8_t shift_interrupt_duration_ms_u16l; uint8_t shift_interrupt_duration_ms_u16h; uint8_t shift_interrupt_current_threshold_percent; // misc uint8_t walk_mode_data_display; // assist levels uint8_t assist_mode_select; uint8_t assist_startup_level; assist_level_t assist_levels[2][10]; } config_t; typedef struct { uint8_t adc_voltage_calibration_steps_x100_i16l; uint8_t adc_voltage_calibration_steps_x100_i16h; } pstate_t; extern config_t g_config; extern pstate_t g_pstate; void cfgstore_init(); bool cfgstore_reset_config(); bool cfgstore_save_config(); bool cfgstore_reset_pstate(); bool cfgstore_save_pstate(); #endif ================================================ FILE: src/firmware/clean.bat ================================================ @ECHO OFF del /s /q *.hex >NUL 2>NUL del /s /q *.ihx >NUL 2>NUL del /s /q *.asm >NUL 2>NUL del /s /q *.rel >NUL 2>NUL del /s /q *.lk >NUL 2>NUL del /s /q *.lst >NUL 2>NUL del /s /q *.rst >NUL 2>NUL del /s /q *.sym >NUL 2>NUL del /s /q *.cdb >NUL 2>NUL del /s /q *.map >NUL 2>NUL del /s /q *.elf >NUL 2>NUL del /s /q *.adb >NUL 2>NUL del /s /q *.mem >NUL 2>NUL @ECHO ON ================================================ FILE: src/firmware/eeprom.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _EEPROM_H_ #define _EEPROM_H_ #include "intellisense.h" #include #include void eeprom_init(); bool eeprom_select_page(int page); int eeprom_read_byte(int offset); bool eeprom_erase_page(); bool eeprom_write_byte(int offset, uint8_t value); bool eeprom_end_write(); #endif ================================================ FILE: src/firmware/eventlog.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "eventlog.h" #include "uart.h" static bool is_enabled; void eventlog_init(bool enabled) { is_enabled = enabled; } bool eventlog_is_enabled() { return is_enabled; } void eventlog_set_enabled(bool enabled) { is_enabled = enabled; } void eventlog_write(uint8_t evt) { if (!is_enabled) { return; } uart_write(0xee); uart_write(evt); uart_write((uint8_t)0xee + evt); } void eventlog_write_data(uint8_t evt, int16_t data) { if (!is_enabled) { return; } uint8_t checksum = 0; uart_write(0xed); checksum += (uint8_t)0xed; uart_write(evt); checksum += evt; uart_write((uint8_t)(data >> 8)); checksum += (uint8_t)(data >> 8); uart_write((uint8_t)data); checksum += (uint8_t)data; uart_write(checksum); } ================================================ FILE: src/firmware/eventlog.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _EVENTLOG_H_ #define _EVENTLOG_H_ #include "intellisense.h" #include #include #define EVT_MSG_MOTOR_INIT_OK 1 #define EVT_MSG_CONFIG_READ_DONE 2 #define EVT_MSG_CONFIG_RESET 3 #define EVT_MSG_CONFIG_WRITE_DONE 4 #define EVT_MSG_CONFIG_READ_BEGIN 5 #define EVT_MSG_CONFIG_WRITE_BEGIN 6 #define EVT_MSG_PSTATE_READ_BEGIN 7 #define EVT_MSG_PSTATE_READ_DONE 8 #define EVT_MSG_PSTATE_WRITE_BEGIN 9 #define EVT_MSG_PSTATE_WRITE_DONE 10 #define EVT_ERROR_INIT_MOTOR 64 #define EVT_ERROR_CHANGE_TARGET_SPEED 65 #define EVT_ERROR_CHANGE_TARGET_CURRENT 66 #define EVT_ERROR_READ_MOTOR_STATUS 67 #define EVT_ERROR_READ_MOTOR_CURRENT 68 #define EVT_ERROR_READ_MOTOR_VOLTAGE 69 #define EVT_ERROR_EEPROM_READ 70 #define EVT_ERROR_EEPROM_WRITE 71 #define EVT_ERROR_EEPROM_ERASE 72 #define EVT_ERROR_EEPROM_VERIFY_VERSION 73 #define EVT_ERROR_EEPROM_VERIFY_CHECKSUM 74 #define EVT_ERROR_THROTTLE_LOW_LIMIT 75 #define EVT_ERROR_THROTTLE_HIGH_LIMIT 76 #define EVT_ERROR_WATCHDOG_TRIGGERED 77 #define EVT_ERROR_EXTCOM_CHEKSUM 78 #define EVT_ERROR_EXTCOM_DISCARD 79 #define EVT_DATA_TARGET_CURRENT 128 #define EVT_DATA_TARGET_SPEED 129 #define EVT_DATA_MOTOR_STATUS 130 #define EVT_DATA_ASSIST_LEVEL 131 #define EVT_DATA_OPERATION_MODE 132 #define EVT_DATA_WHEEL_SPEED_PPM 133 #define EVT_DATA_LIGHTS 134 #define EVT_DATA_TEMPERATURE 135 #define EVT_DATA_THERMAL_LIMITING 136 #define EVT_DATA_SPEED_LIMITING 137 #define EVT_DATA_MAX_CURRENT_ADC_REQUEST 138 #define EVT_DATA_MAX_CURRENT_ADC_RESPONSE 139 #define EVT_DATA_MAIN_LOOP_TIME 140 #define EVT_DATA_THROTTLE_ADC 141 #define EVT_DATA_LVC_LIMITING 142 #define EVT_DATA_SHIFT_SENSOR 143 #define EVT_DATA_BBSHD_THERMISTOR 144 #define EVT_DATA_VOLTAGE 145 #define EVT_DATA_CALIBRATE_VOLTAGE 146 #define EVT_DATA_TORQUE_ADC 147 #define EVT_DATA_TORQUE_ADC_CALIBRATED 148 void eventlog_init(bool enabled); bool eventlog_is_enabled(); void eventlog_set_enabled(bool enabled); void eventlog_write(uint8_t evt); void eventlog_write_data(uint8_t evt, int16_t data); #endif ================================================ FILE: src/firmware/extcom.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "extcom.h" #include "cfgstore.h" #include "eventlog.h" #include "uart.h" #include "system.h" #include "sensors.h" #include "motor.h" #include "battery.h" #include "app.h" #include "util.h" #include "version.h" #include "intellisense.h" #include "fwconfig.h" #include #include #include #define KEEP 0 #define DISCARD -1 #define BUFFER_SIZE 192 #define DISCARD_TIMEOUT_MS 50 #define REQUEST_TYPE_READ 0x01 #define REQUEST_TYPE_WRITE 0x02 #define REQUEST_TYPE_BAFANG_READ 0x11 #define REQUEST_TYPE_BAFANG_WRITE 0x16 // Firmware config tool communication #define OPCODE_READ_FW_VERSION 0x01 #define OPCODE_READ_EVTLOG_ENABLE 0x02 #define OPCODE_READ_CONFIG 0x03 #define OPCODE_READ_STATUS 0x04 #define OPCODE_WRITE_EVTLOG_ENABLE 0xf0 #define OPCODE_WRITE_CONFIG 0xf1 #define OPCODE_WRITE_RESET_CONFIG 0xf2 #define OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION 0xf3 // Bafang display communication #define OPCODE_BAFANG_DISPLAY_READ_STATUS 0x08 #define OPCODE_BAFANG_DISPLAY_READ_CURRENT 0x0a #define OPCODE_BAFANG_DISPLAY_READ_BATTERY 0x11 #define OPCODE_BAFANG_DISPLAY_READ_SPEED 0x20 #define OPCODE_BAFANG_DISPLAY_READ_UNKNOWN1 0x21 #define OPCODE_BAFANG_DISPLAY_READ_RANGE 0x22 #define OPCODE_BAFANG_DISPLAY_READ_CALORIES 0x24 #define OPCODE_BAFANG_DISPLAY_READ_UNKNOWN3 0x25 #define OPCODE_BAFANG_DISPLAY_READ_MOVING 0x31 #define OPCODE_BAFANG_DISPLAY_WRITE_PAS 0x0b #define OPCODE_BAFANG_DISPLAY_WRITE_MODE 0x0c #define OPCODE_BAFANG_DISPLAY_WRITE_LIGHTS 0x1a #define OPCODE_BAFANG_DISPLAY_WRITE_SPEED_LIM 0x1f // Bafang config tool communication (not supported, just discard messages) #define OPCODE_BAFANG_TOOL_READ_CONNECT 0x51 #define OPCODE_BAFANG_TOOL_READ_BASIC 0x52 #define OPCODE_BAFANG_TOOL_READ_PAS 0x53 #define OPCODE_BAFANG_TOOL_READ_THROTTLE 0x54 #define OPCODE_BAFANG_TOOL_WRITE_BASIC 0x52 #define OPCODE_BAFANG_TOOL_WRITE_PAS 0x53 #define OPCODE_BAFANG_TOOL_WRITE_THROTTLE 0x54 static uint8_t msg_len; static uint8_t msgbuf[BUFFER_SIZE]; static uint32_t last_recv_ms; static uint32_t discard_until_ms; static uint8_t compute_checksum(uint8_t* buf, uint8_t length); static void write_uart_and_increment_checksum(uint8_t data, uint8_t* checksum); static int16_t try_process_request(); static int16_t try_process_read_request(); static int16_t try_process_write_request(); static int16_t try_process_bafang_read_request(); static int16_t try_process_bafang_write_request(); static int16_t process_read_fw_version(); static int16_t process_read_evtlog_enable(); static int16_t process_read_config(); static int16_t process_read_status(); static int16_t process_write_evtlog_enable(); static int16_t process_write_config(); static int16_t process_write_reset_config(); static int16_t process_write_adc_voltage_calibration(); static int16_t process_bafang_display_read_status(); static int16_t process_bafang_display_read_current(); static int16_t process_bafang_display_read_battery(); static int16_t process_bafang_display_read_speed(); static int16_t process_bafang_display_read_unknown1(); static int16_t process_bafang_display_read_range(); static int16_t process_bafang_display_read_calories(); static int16_t process_bafang_display_read_unknown3(); static int16_t process_bafang_display_read_moving(); static int16_t process_bafang_display_write_pas(); static int16_t process_bafang_display_write_mode(); static int16_t process_bafang_display_write_lights(); static int16_t process_bafang_display_write_speed_limit(); void extcom_init() { msg_len = 0; last_recv_ms = 0; discard_until_ms = 0; // Bafang standard baud rate uart_open(1200); // Wait one second for config tool connection. // This is here to that the config tool can enable // the event log before system proceeds with initialization. uint32_t end = system_ms() + 1000; while (system_ms() < end) { extcom_process(); system_delay_ms(10); } } void extcom_process() { uint32_t now = system_ms(); while (uart_available()) { if (msg_len == BUFFER_SIZE || (discard_until_ms != 0 && now < discard_until_ms)) { // communication error, reset msg_len = 0; while (uart_available()) uart_read(); } else { msgbuf[msg_len++] = uart_read(); last_recv_ms = now; discard_until_ms = 0; } } if (msg_len > 0 && now - last_recv_ms > 100) { // communication error, reset msg_len = 0; } int16_t res = try_process_request(); if (res == DISCARD) { msg_len = 0; last_recv_ms = 0; // Discard received data for the next DISCARD_TIMEOUT_MS milliseconds discard_until_ms = now + DISCARD_TIMEOUT_MS; eventlog_write(EVT_ERROR_EXTCOM_DISCARD); } else if (res > 0) { if (res < msg_len) { // will not occur due to request/response communication memcpy(msgbuf, msgbuf + res, msg_len - res); msg_len -= res; } else { msg_len = 0; last_recv_ms = 0; } } } static uint8_t compute_checksum(uint8_t* buf, uint8_t length) { uint8_t result = 0; for (uint8_t i = 0; i < length; ++i) { result += buf[i]; } return result; } static void write_uart_and_increment_checksum(uint8_t data, uint8_t* checksum) { *checksum += data; uart_write(data); } static int16_t try_process_request() { if (msg_len < 1) { return KEEP; } switch (msgbuf[0]) { case REQUEST_TYPE_READ: return try_process_read_request(); case REQUEST_TYPE_WRITE: return try_process_write_request(); case REQUEST_TYPE_BAFANG_READ: return try_process_bafang_read_request(); case REQUEST_TYPE_BAFANG_WRITE: return try_process_bafang_write_request(); } return DISCARD; // unknown message } static int16_t try_process_read_request() { if (msg_len < 2) { return KEEP; } switch (msgbuf[1]) { case OPCODE_READ_FW_VERSION: return process_read_fw_version(); case OPCODE_READ_EVTLOG_ENABLE: return process_read_evtlog_enable(); case OPCODE_READ_CONFIG: return process_read_config(); case OPCODE_READ_STATUS: return process_read_status(); } return DISCARD; } static int16_t try_process_write_request() { if (msg_len < 2) { return KEEP; } switch (msgbuf[1]) { case OPCODE_WRITE_EVTLOG_ENABLE: return process_write_evtlog_enable(); case OPCODE_WRITE_CONFIG: return process_write_config(); case OPCODE_WRITE_RESET_CONFIG: return process_write_reset_config(); case OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION: return process_write_adc_voltage_calibration(); } return DISCARD; } static int16_t try_process_bafang_read_request() { if (msg_len < 2) { return KEEP; } switch (msgbuf[1]) { case OPCODE_BAFANG_DISPLAY_READ_STATUS: return process_bafang_display_read_status(); case OPCODE_BAFANG_DISPLAY_READ_CURRENT: return process_bafang_display_read_current(); case OPCODE_BAFANG_DISPLAY_READ_BATTERY: return process_bafang_display_read_battery(); case OPCODE_BAFANG_DISPLAY_READ_SPEED: return process_bafang_display_read_speed(); case OPCODE_BAFANG_DISPLAY_READ_UNKNOWN1: return process_bafang_display_read_unknown1(); case OPCODE_BAFANG_DISPLAY_READ_RANGE: return process_bafang_display_read_range(); case OPCODE_BAFANG_DISPLAY_READ_CALORIES: return process_bafang_display_read_calories(); case OPCODE_BAFANG_DISPLAY_READ_UNKNOWN3: return process_bafang_display_read_unknown3(); case OPCODE_BAFANG_DISPLAY_READ_MOVING: return process_bafang_display_read_moving(); } return DISCARD; } static int16_t try_process_bafang_write_request() { if (msg_len < 2) { return KEEP; } switch (msgbuf[1]) { case OPCODE_BAFANG_DISPLAY_WRITE_PAS: return process_bafang_display_write_pas(); case OPCODE_BAFANG_DISPLAY_WRITE_MODE: return process_bafang_display_write_mode(); case OPCODE_BAFANG_DISPLAY_WRITE_LIGHTS: return process_bafang_display_write_lights(); case OPCODE_BAFANG_DISPLAY_WRITE_SPEED_LIM: return process_bafang_display_write_speed_limit(); } return DISCARD; } static int16_t process_read_fw_version() { if (msg_len < 3) { return KEEP; } if (compute_checksum(msgbuf, 2) == msgbuf[2]) { uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_READ, &checksum); write_uart_and_increment_checksum(OPCODE_READ_FW_VERSION, &checksum); write_uart_and_increment_checksum(VERSION_MAJOR, &checksum); write_uart_and_increment_checksum(VERSION_MINOR, &checksum); write_uart_and_increment_checksum(VERSION_PATCH, &checksum); write_uart_and_increment_checksum(CONFIG_VERSION, &checksum); write_uart_and_increment_checksum(CTRL_TYPE, &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 3; } static int16_t process_read_evtlog_enable() { if (msg_len < 3) { return KEEP; } if (compute_checksum(msgbuf, 2) == msgbuf[2]) { uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_READ, &checksum); write_uart_and_increment_checksum(OPCODE_READ_EVTLOG_ENABLE, &checksum); write_uart_and_increment_checksum((uint8_t)eventlog_is_enabled(), &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 3; } static int16_t process_read_config() { if (msg_len < 3) { return KEEP; } if (compute_checksum(msgbuf, 2) == msgbuf[2]) { uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_READ, &checksum); write_uart_and_increment_checksum(OPCODE_READ_CONFIG, &checksum); write_uart_and_increment_checksum(CONFIG_VERSION, &checksum); write_uart_and_increment_checksum(sizeof(config_t), &checksum); uint8_t* cfg = (uint8_t*)&g_config; for (uint8_t i = 0; i < sizeof(config_t); ++i) { write_uart_and_increment_checksum(*(cfg + i), &checksum); } uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 3; } static int16_t process_read_status() { // :TODO: return 0; } static int16_t process_write_evtlog_enable() { if (msg_len < 4) { return KEEP; } if (compute_checksum(msgbuf, 3) == msgbuf[3]) { eventlog_set_enabled((bool)msgbuf[2]); uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_WRITE, &checksum); write_uart_and_increment_checksum(OPCODE_WRITE_EVTLOG_ENABLE, &checksum); write_uart_and_increment_checksum(msgbuf[2], &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 4; } static int16_t process_write_config() { if (msg_len < 4) { return KEEP; } uint8_t version = msgbuf[2]; uint8_t length = msgbuf[3]; if (msg_len < 4 + length + 1) { return KEEP; } if (compute_checksum(msgbuf, (uint8_t)(4 + sizeof(config_t))) == msgbuf[4 + sizeof(config_t)]) { bool result = false; if (version == CONFIG_VERSION && length == sizeof(config_t)) { memcpy(&g_config, msgbuf + 4, sizeof(config_t)); result = cfgstore_save_config(); } uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_WRITE, &checksum); write_uart_and_increment_checksum(OPCODE_WRITE_CONFIG, &checksum); write_uart_and_increment_checksum(result, &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 4 + length + 1; } static int16_t process_write_reset_config() { if (msg_len < 3) { return KEEP; } if (compute_checksum(msgbuf, 2) == msgbuf[2]) { bool res = cfgstore_reset_config(); uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_WRITE, &checksum); write_uart_and_increment_checksum(OPCODE_WRITE_RESET_CONFIG, &checksum); write_uart_and_increment_checksum((uint8_t)res, &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 3; } static int16_t process_write_adc_voltage_calibration() { if (msg_len < 5) { return KEEP; } if (compute_checksum(msgbuf, 4) == msgbuf[4]) { uint16_t actual_volt_x100 = ((uint16_t)msgbuf[2] << 8) | msgbuf[3]; int16_t calibration_offset = motor_calibrate_battery_voltage(actual_volt_x100); g_pstate.adc_voltage_calibration_steps_x100_i16l = (uint8_t)(calibration_offset); g_pstate.adc_voltage_calibration_steps_x100_i16h = (uint8_t)(calibration_offset >> 8); cfgstore_save_pstate(); uint8_t checksum = 0; write_uart_and_increment_checksum(REQUEST_TYPE_WRITE, &checksum); write_uart_and_increment_checksum(OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION, &checksum); write_uart_and_increment_checksum(msgbuf[2], &checksum); write_uart_and_increment_checksum(msgbuf[3], &checksum); uart_write(checksum); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 5; } static int16_t process_bafang_display_read_status() { if (msg_len < 2) { return KEEP; } uart_write(app_get_status_code()); return 2; } static int16_t process_bafang_display_read_current() { if (msg_len < 2) { return KEEP; } uint8_t amp_x2 = (uint8_t)((motor_get_battery_current_x10() * 2) / 10); uart_write(amp_x2); uart_write(amp_x2); // checksum return 2; } static int16_t process_bafang_display_read_battery() { if (msg_len < 2) { return KEEP; } uint8_t value = battery_get_mapped_percent(); uart_write(value); uart_write(value); // checksum return 2; } static int16_t process_bafang_display_read_speed() { if (msg_len < 2) { return KEEP; } uint16_t speed = 0; if (g_config.walk_mode_data_display != WALK_MODE_DATA_SPEED && app_get_assist_level() == ASSIST_PUSH) { uint16_t data = 0; switch (g_config.walk_mode_data_display) { case WALK_MODE_DATA_TEMPERATURE: // Keep temperature in C, farenheit would be out of range data = app_get_temperature(); break; case WALK_MODE_DATA_REQUESTED_POWER: data = motor_get_target_current(); break; case WALK_MODE_DATA_BATTERY_PERCENT: data = battery_get_percent(); break; } if (g_config.use_freedom_units) { // Compensate for kph -> mph conversion display will do. data = (data * 161) / 100; } // T_kph -> rpm speed = (uint16_t)(25000.f / (3 * 3.14159f * 1.27f * EXPAND_U16(g_config.wheel_size_inch_x10_u16h, g_config.wheel_size_inch_x10_u16l)) * data); } else { speed = speed_sensor_get_rpm_x10() / 10; } uint8_t checksum = 0; write_uart_and_increment_checksum(speed >> 8, &checksum); write_uart_and_increment_checksum((uint8_t)speed, &checksum); uart_write(checksum + (uint8_t)0x20); // weird checksum return 2; } static int16_t process_bafang_display_read_unknown1() { if (msg_len < 3) { return KEEP; } uart_write(0x00); uart_write(0x00); uart_write(0x00); // checksum return 3; } static int16_t process_bafang_display_read_range() { if (msg_len < 3) { return KEEP; } uint16_t value = 0; #if DISPLAY_RANGE_FIELD_DATA == DISPLAY_RANGE_FIELD_TEMPERATURE value = app_get_temperature(); if (g_config.use_freedom_units) { // Convert to farenheit and compensate for the km -> miles conversion the diplay will do // F_miles = (C * 9/5 + 32) * 161 / 100 // Approximistation: // F_miles = 2.9C + 50.5 value = ((290u * value) + 5050u) / 100u; } #elif DISPLAY_RANGE_FIELD_DATA == DISPLAY_RANGE_FIELD_POWER if (app_get_lights()) { value = motor_get_battery_current_x10(); } else { uint16_t max_current_amp_x10 = g_config.max_current_amps * 10; value = MAP32(motor_get_target_current(), 0, 100, 0, max_current_amp_x10); } if (g_config.use_freedom_units) { // compensate for km -> miles conversion the display will do value = (value * 161u) / 100u; } #endif uint8_t checksum = 0; write_uart_and_increment_checksum((uint8_t)(value >> 8), &checksum); write_uart_and_increment_checksum((uint8_t)value, &checksum); uart_write(checksum); // checksum return 3; } static int16_t process_bafang_display_read_calories() { if (msg_len < 3) { return KEEP; } uint8_t checksum = 0; // send battery voltage x10 to show in calories field uint16_t volt = motor_get_battery_voltage_x10(); write_uart_and_increment_checksum(volt >> 8, & checksum); write_uart_and_increment_checksum(volt & 0xff, & checksum); uart_write(checksum); // checksum return 3; } static int16_t process_bafang_display_read_unknown3() { if (msg_len < 3) { return KEEP; } uart_write(0x00); uart_write(0x00); uart_write(0x00); uart_write(0x00); uart_write(0x00); // checksum return 3; } static int16_t process_bafang_display_read_moving() { if (msg_len < 2) { return KEEP; } uint8_t data = speed_sensor_is_moving() ? 0x31 : 0x30; uart_write(data); uart_write(data); // checksum return 2; } static int16_t process_bafang_display_write_pas() { if (msg_len < 4) { return KEEP; } if (compute_checksum(msgbuf, 3) == msgbuf[3]) { switch (msgbuf[2]) { case 0x00: app_set_assist_level(ASSIST_0); break; case 0x01: app_set_assist_level(ASSIST_1); break; case 0x0b: app_set_assist_level(ASSIST_2); break; case 0x0c: app_set_assist_level(ASSIST_3); break; case 0x0d: app_set_assist_level(ASSIST_4); break; case 0x02: app_set_assist_level(ASSIST_5); break; case 0x15: app_set_assist_level(ASSIST_6); break; case 0x16: app_set_assist_level(ASSIST_7); break; case 0x17: app_set_assist_level(ASSIST_8); break; case 0x03: app_set_assist_level(ASSIST_9); break; case 0x06: app_set_assist_level(ASSIST_PUSH); break; default: // Unsupported level, ignore break; } } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 4; } static int16_t process_bafang_display_write_mode() { if (msg_len < 4) { return KEEP; } if (compute_checksum(msgbuf, 3) == msgbuf[3]) { switch (msgbuf[2]) { case 0x02: app_set_operation_mode(OPERATION_MODE_DEFAULT); break; case 0x04: app_set_operation_mode(OPERATION_MODE_SPORT); break; default: // Unsupported mode, ignore break; } } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } return 4; } static int16_t process_bafang_display_write_lights() { if (msg_len < 3) { return KEEP; } // No checksum switch (msgbuf[2]) { case 0xf0: app_set_lights(false); break; case 0xf1: app_set_lights(true); break; default: return DISCARD; // unsupported state, assume communication error } return 3; } static int16_t process_bafang_display_write_speed_limit() { if (msg_len < 5) { return KEEP; } /* if (compute_checksum(msgbuf, 4) == msgbuf[4]) { // Ignoring speed limit requested by display, // Global speed limit is configured in firmware config tool. uint16_t value = ((msgbuf[2] << 8) | msgbuf[3]); app_set_wheel_max_speed_rpm(value); } else { eventlog_write(EVT_ERROR_EXTCOM_CHEKSUM); return DISCARD; } */ return 5; } ================================================ FILE: src/firmware/extcom.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _EXTCOM_H_ #define _EXTCOM_H_ void extcom_init(); void extcom_process(); #endif ================================================ FILE: src/firmware/fwconfig.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _FWCONFIG_H_ #define _FWCONFIG_H_ #if defined(BBSHD) #define HAS_MOTOR_TEMP_SENSOR 1 #else #define HAS_MOTOR_TEMP_SENSOR 0 #endif #if defined(BBSHD) || defined(BBS02) #define HAS_CONTROLLER_TEMP_SENSOR 1 #else #define HAS_CONTROLLER_TEMP_SENSOR 0 #endif #if defined(TSDZ2) #define HAS_TORQUE_SENSOR 1 #else #define HAS_TORQUE_SENSOR 0 #endif #if defined(BBSHD) || defined(BBS02) #define HAS_SHIFT_SENSOR_SUPPORT 1 #else #define HAS_SHIFT_SENSOR_SUPPORT 0 #endif #if defined(BBS02) #define MAX_CADENCE_RPM_X10 1500 #elif defined(BBSHD) // Measured on BBSHD at 48V #define MAX_CADENCE_RPM_X10 1680 #else #define MAX_CADENCE_RPM_X10 1200 #endif #if defined(BBS02) || defined(BBSHD) #define PAS_PULSES_REVOLUTION 24 #elif defined(TSDZ2) #define PAS_PULSES_REVOLUTION 20 #endif // Applied to both motor and controller tmeperature sensor #define MAX_TEMPERATURE 85 // Current ramp down starts at MAX_TEMPERATURE - 5. #define MAX_TEMPERATURE_RAMP_DOWN_INTERVAL 5 // Maximum allowed motor current in percent of maximum configured current (A) // to still apply when maximum temperature has been reached. // Motor current is ramped down linearly until this value when approaching // max temperature. #define MAX_TEMPERATURE_LOW_CURRENT_PERCENT 20 // No battery percent mapping #define BATTERY_PERCENT_MAP_NONE 0 // Map battery percent to provide a linear relationship on the // 5-bar battery indicator of the SW102 display. #define BATTERY_PERCENT_MAP_SW102 1 // Select battery percent mapping #define BATTERY_PERCENT_MAP BATTERY_PERCENT_MAP_NONE // Time with no motor load until battery voltage is updated to avoid voltage sag. #define BATTERY_NO_LOAD_DELAY_MS 2000 // Padding values for voltage range of battery. #define BATTERY_FULL_OFFSET_PERCENT 8 #define BATTERY_EMPTY_OFFSET_PERCENT 8 // Battery SOC percentage when current ramp down starts. #define LVC_RAMP_DOWN_OFFSET_PERCENT 10 // Maximum allowed motor current in percent of maximum configured current (A) // to still apply when 0% battery has been reached. // Motor current is ramped down linearly until this value when approaching "empty". #define LVC_LOW_CURRENT_PERCENT 20 // Size of speed limit ramp down interval. // If max speed is 50 and this is set to 3 then the // target current will start ramping down when passing 47 // and be at 50% of assist target current when reaching 50. #define SPEED_LIMIT_RAMP_DOWN_INTERVAL_KPH 3 // Current ramp down (e.g. when releasing throttle, stop pedaling etc.) in percent per 10 millisecond. // Specifying 1 will make ramp down periond 1 second if releasing from full throttle. // Set to 100 to disable #define CURRENT_RAMP_DOWN_PERCENT_10MS 5 // Target speed in km/h when walk mode is engaged #define WALK_MODE_SPEED_KPH 4 #define THROTTLE_RESPONSE_LINEAR 1 #define THROTTLE_RESPONSE_QUADRATIC 2 #define THROTTLE_RESPONSE_CUSTOM 3 #define THROTTLE_RESPONSE_CURVE THROTTLE_RESPONSE_CUSTOM // Custom throttle map // y = pow(x / 100.0, 1.5) * 100.0 #define THROTTLE_CUSTOM_MAP \ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, \ 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, \ 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, \ 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, \ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, \ 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, \ 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, \ 59, 60, 61, 62, 64, 65, 66, 68, 69, 70, \ 72, 73, 74, 76, 77, 78, 80, 81, 83, 84, \ 85, 87, 88, 90, 91, 93, 94, 96, 97, 99, \ 100 // This value is used when assist level is configured with throttle cadence // override flag in config tool. Default is 100%. #define THROTTLE_CADENCE_OVERRIDE_PERCENT 100 // Lower limit for cadence rpm in power calculation // for torque pas assist. When cadence is below this // limit you will get extra power. // // power_w = torque_Nm * cadence_rpm * 0.105 // // The calculated power is then multipled by a factor // set by the assist level to get the final power which // the motor will contribute. // // The value configured below is the minimum value for // cadence_rpm to be used in the formula above. If the // actual cadence is lower it will be overriden by this // configured value. #define TORQUE_POWER_LOWER_RPM_X10 300 // Number of PAS sensor pulses to engage cruise mode, // there are 24 pulses per revolution. #define CRUISE_ENGAGE_PAS_PULSES PAS_PULSES_REVOLUTION / 2 // Number of PAS sensor pulses to disengage curise mode // by pedaling backwards. #define CRUISE_DISENGAGE_PAS_PULSES PAS_PULSES_REVOLUTION / 2 // Option to control what data is displayed in "Range" field on display // since range calculation is not implemented. #define DISPLAY_RANGE_FIELD_ZERO 0 #define DISPLAY_RANGE_FIELD_TEMPERATURE 1 // max temperature of controller / motor #define DISPLAY_RANGE_FIELD_POWER 2 // requested current x10 (lights off) / actual current x10 (lights on) // uncomment and select option above // #define DISPLAY_RANGE_FIELD_DATA DISPLAY_RANGE_FIELD_ZERO // default to temperature if temperature sensors available (BBS2/BBSHD), else power (TSDZ2) #ifndef DISPLAY_RANGE_FIELD_DATA #if HAS_CONTROLLER_TEMP_SENSOR || HAS_MOTOR_TEMP_SENSOR #define DISPLAY_RANGE_FIELD_DATA DISPLAY_RANGE_FIELD_TEMPERATURE #else #define DISPLAY_RANGE_FIELD_DATA DISPLAY_RANGE_FIELD_POWER #endif #endif #endif ================================================ FILE: src/firmware/intellisense.h ================================================ #ifndef _INTELLISENSE_H_ #define _INTELLISENSE_H_ // NOTE: // The defines below are here to keep IntelliSense // in Visual Studio happy and not throw incorrect errors. #if !defined (SDCC) && !defined (__SDCC) #define INTERRUPT(name, vector) void name() #define INTERRUPT_USING(name, vector,regnum) void name() #define __interrupt(vector) #define enableInterrupts() #define disableInterrupts() #define NOP() #define _Bool uint8_t #endif #endif ================================================ FILE: src/firmware/interrupt.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _INTERRUPT_H_ #define _INTERRUPT_H_ // Interrupt rouines declarations required to be included from main.c #if defined(BBSHD) || defined(BBS02) #include "bbsx/interrupt.h" #elif defined(TSDZ2) #include "tsdz2/interrupt.h" #endif #endif ================================================ FILE: src/firmware/lights.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _LIGHTS_H_ #define _LIGHTS_H_ #include "intellisense.h" #include #include void lights_init(); void lights_enable(); void lights_disable(); void lights_set(bool on); #endif ================================================ FILE: src/firmware/main.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "interrupt.h" // IMPORTANT: interrupt vector declarations must be included from main.c! #include "timers.h" #include "system.h" #include "eeprom.h" #include "cfgstore.h" #include "eventlog.h" #include "app.h" #include "battery.h" #include "watchdog.h" #include "adc.h" #include "motor.h" #include "extcom.h" #include "sensors.h" #include "throttle.h" #include "lights.h" #include "uart.h" #include "util.h" #define APP_PROCESS_INTERVAL_MS 5 void main(void) { motor_pre_init(); watchdog_init(); timers_init(); system_init(); eventlog_init(false); extcom_init(); if (watchdog_triggered()) { // force write watchdog reset to eventlog bool prev = eventlog_is_enabled(); eventlog_set_enabled(true); eventlog_write(EVT_ERROR_WATCHDOG_TRIGGERED); eventlog_set_enabled(prev); } eeprom_init(); cfgstore_init(); adc_init(); sensors_init(); speed_sensor_set_signals_per_rpm(g_config.speed_sensor_signals); pas_set_stop_delay((uint16_t)g_config.pas_stop_delay_x100s * 10); battery_init(); throttle_init( EXPAND_U16(g_config.throttle_start_voltage_mv_u16h, g_config.throttle_start_voltage_mv_u16l), EXPAND_U16(g_config.throttle_end_voltage_mv_u16h, g_config.throttle_end_voltage_mv_u16l) ); motor_init(g_config.max_current_amps * 1000, g_config.low_cut_off_v, EXPAND_I16(g_pstate.adc_voltage_calibration_steps_x100_i16h, g_pstate.adc_voltage_calibration_steps_x100_i16l)); lights_init(); app_init(); uint32_t next_app_proccess = system_ms(); while (1) { uint32_t now = system_ms(); adc_process(); motor_process(); if (now >= next_app_proccess) { next_app_proccess = now + APP_PROCESS_INTERVAL_MS; battery_process(); sensors_process(); extcom_process(); app_process(); } watchdog_yeild(); } } ================================================ FILE: src/firmware/motor.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _MOTOR_H_ #define _MOTOR_H_ #include #define MOTOR_ERROR_LVC 0x0800 #define MOTOR_ERROR_HALL_SENSOR 0x2000 #define MOTOR_ERROR_CURRENT_SENSE 0x0004 #define MOTOR_ERROR_POWER_RESET 0x0020 void motor_pre_init(); void motor_init(uint16_t max_current_mA, uint8_t lvc_V, int16_t adc_calib_volt_step_offset); void motor_process(); void motor_enable(); void motor_disable(); uint16_t motor_status(); uint8_t motor_get_target_speed(); uint8_t motor_get_target_current(); void motor_set_target_speed(uint8_t percent); void motor_set_target_current(uint8_t percent); int16_t motor_calibrate_battery_voltage(uint16_t actual_voltage_x100); uint16_t motor_get_battery_lvc_x10(); uint16_t motor_get_battery_current_x10(); uint16_t motor_get_battery_voltage_x10(); #endif ================================================ FILE: src/firmware/sensors.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _SENSORS_H_ #define _SENSORS_H_ #include "intellisense.h" #include #include void sensors_init(); void sensors_process(); void pas_set_stop_delay(uint16_t delay_ms); uint16_t pas_get_cadence_rpm_x10(); uint16_t pas_get_pulse_counter(); bool pas_is_pedaling_forwards(); bool pas_is_pedaling_backwards(); void speed_sensor_set_signals_per_rpm(uint8_t num_signals); bool speed_sensor_is_moving(); uint16_t speed_sensor_get_rpm_x10(); uint16_t torque_sensor_get_nm_x100(); bool torque_sensor_ok(); int16_t temperature_contr_x100(); int16_t temperature_motor_x100(); bool brake_is_activated(); bool shift_sensor_is_activated(); #endif ================================================ FILE: src/firmware/system.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _SYSTEM_H_ #define _SYSTEM_H_ #include "version.h" #include #if defined(BBSHD) || defined(BBS02) #include "bbsx/cpu.h" #elif defined(TSDZ2) #include "tsdz2/cpu.h" #endif void system_init(); uint32_t system_ms(); void system_delay_ms(uint16_t ms); #endif ================================================ FILE: src/firmware/throttle.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "throttle.h" #include "intellisense.h" #include "system.h" #include "eventlog.h" #include "util.h" #include "adc.h" #include "fwconfig.h" #include static uint8_t min_voltage_adc; static uint8_t max_voltage_adc; static bool throttle_detected; static bool throttle_low_ok; static bool throttle_hard_ok; static uint32_t throttle_hard_limit_hit_at; //#define LOG_THROTTLE_ADC #define ADC_VOLTAGE_MV 5000ul #define THROTTLE_HARD_LOW_LIMIT_MV 500ul #define THROTTLE_HARD_HIGH_LIMIT_MV 4500ul #define THROTTLE_HARD_LOW_LIMIT_ADC ((THROTTLE_HARD_LOW_LIMIT_MV * 256) / ADC_VOLTAGE_MV) #define THROTTLE_HARD_HIGH_LIMIT_ADC ((THROTTLE_HARD_HIGH_LIMIT_MV * 256) / ADC_VOLTAGE_MV) #define THROTTLE_HARD_LIMIT_TOLERANCE_MS 100 #if (THROTTLE_RESPONSE_CURVE == THROTTLE_RESPONSE_CUSTOM) static const uint8_t throttle_custom_map_lut[101] = { THROTTLE_CUSTOM_MAP }; #endif void throttle_init(uint16_t min_mv, uint16_t max_mv) { min_voltage_adc = (uint8_t)(((uint32_t)min_mv * 256) / ADC_VOLTAGE_MV); max_voltage_adc = (uint8_t)(((uint32_t)max_mv * 256) / ADC_VOLTAGE_MV); throttle_detected = false; throttle_low_ok = false; throttle_hard_ok = true; throttle_hard_limit_hit_at = 0; } bool throttle_ok() { return !throttle_detected || (throttle_low_ok && throttle_hard_ok); } uint8_t throttle_read() { static uint8_t throttle_percent = 0; int16_t value = adc_get_throttle(); #ifdef LOG_THROTTLE_ADC static uint8_t last_logged_throttle_adc = 0; if (ABS(value - last_logged_throttle_adc) > 1) { last_logged_throttle_adc = value; eventlog_write_data(EVT_DATA_THROTTLE_ADC, value); } #endif if (value < THROTTLE_HARD_LOW_LIMIT_ADC || value > THROTTLE_HARD_HIGH_LIMIT_ADC) { // allow invalid throttle input value for a number of milliseconds before reporting throttle error. if (throttle_hard_limit_hit_at != 0) { if (throttle_hard_ok && (system_ms() - throttle_hard_limit_hit_at) > THROTTLE_HARD_LIMIT_TOLERANCE_MS) { if (throttle_detected && value < THROTTLE_HARD_LOW_LIMIT_ADC) { eventlog_write(EVT_ERROR_THROTTLE_LOW_LIMIT); } else if (value > THROTTLE_HARD_HIGH_LIMIT_ADC) { eventlog_write(EVT_ERROR_THROTTLE_HIGH_LIMIT); } throttle_hard_ok = false; } } else { throttle_hard_limit_hit_at = system_ms(); } } else { if (value >= THROTTLE_HARD_LOW_LIMIT_ADC) { throttle_detected = true; } throttle_hard_limit_hit_at = 0; throttle_hard_ok = true; } if (value < min_voltage_adc) { // throttle is considered not working until it has given a signal below minimum // configured value but more than 0. throttle_low_ok = true; // hysteresis if (throttle_percent > 0) { value += 1; } if (value < min_voltage_adc) { throttle_percent = 0; return throttle_percent; } } if (value > max_voltage_adc) { value = max_voltage_adc; } throttle_percent = (uint8_t)MAP16(value, min_voltage_adc, max_voltage_adc, 1, 100); return throttle_percent; } uint8_t throttle_map_response(uint8_t throttle_percent) { #if (THROTTLE_RESPONSE_CURVE == THROTTLE_RESPONSE_QUADRATIC) return (uint8_t)(((uint16_t)throttle_percent * throttle_percent) / 100); #elif (THROTTLE_RESPONSE_CURVE == THROTTLE_RESPONSE_CUSTOM) return throttle_custom_map_lut[throttle_percent]; #else return throttle_percent; #endif } ================================================ FILE: src/firmware/throttle.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _THROTTLE_H_ #define _THROTTLE_H_ #include "intellisense.h" #include #include void throttle_init(uint16_t min_mv, uint16_t max_mv); bool throttle_ok(); uint8_t throttle_read(); uint8_t throttle_map_response(uint8_t throttle_percent); #endif ================================================ FILE: src/firmware/timers.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _TIMER_H_ #define _TIMER_H_ void timers_init(); #endif ================================================ FILE: src/firmware/tohex.bat ================================================ @echo off packihx bbs-fw.ihx > bbs-fw.hex ================================================ FILE: src/firmware/tsdz2/adc.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include #include "adc.h" #include "tsdz2/interrupt.h" #include "tsdz2/stm8.h" #include "tsdz2/pins.h" #include "tsdz2/stm8s/stm8s_adc1.h" #include "tsdz2/stm8s/stm8s.h" static volatile uint8_t adc_throttle; static volatile uint16_t adc_battery_voltage; static volatile uint16_t adc_torque; // cached variables read from voltatile uint16_t vars while ADC1 interrupt disabled static uint16_t adc_battery_voltage_cache; static uint16_t adc_torque_cache; void adc_init() { SET_PIN_INPUT(PIN_BATTERY_CURRENT); SET_PIN_INPUT(PIN_BATTERY_VOLTAGE); SET_PIN_INPUT(PIN_THROTTLE); SET_PIN_INPUT(PIN_TORQUE_SENSOR); // NOTE: // adc configuration (except ADC1->CR1) is overwritten in motor.c/isr_timer1_cmp // which triggeres the conversion. // // The motor control interrupt routines performs single mode // adc conversion of battery current, reads the result and // then starts buffered scan mode conversion of all adc channels // with end of conversion interrupt enabled which is handled here. ADC1->CR1 = ADC1_PRESSEL_FCPU_D2; ADC1->CR2 = ADC1_ALIGN_LEFT; // channel (none) ADC1->CSR = 0x00; // schmittrig disable all ADC1->TDRL |= (uint8_t)0xFF; ADC1->TDRH |= (uint8_t)0xFF; // Enable the ADC1 peripheral ADC1->CR1 |= ADC1_CR1_ADON; } void adc_process() { // Have to disable interrupts globally since ADC1->CSR register // is manipulated from motor control isr. Very short time, should have no effect. disableInterrupts(); adc_battery_voltage_cache = adc_battery_voltage; // adc_battery_voltage; adc_torque_cache = adc_torque; enableInterrupts(); } uint8_t adc_get_throttle() { // atomic read return adc_throttle; } uint16_t adc_get_torque() { // 10 bit resolution return adc_torque_cache; } uint16_t adc_get_temperature_contr() { return 0; } uint16_t adc_get_temperature_motor() { return 0; } uint16_t adc_get_battery_voltage() { return adc_battery_voltage_cache; } void isr_adc1(void) __interrupt(ITC_IRQ_ADC1) { if (ADC1->CSR & ADC1_CSR_EOC) { // all adc channels converted, data available in buffers // clear EOC and disable EOC interrupt ADC1->CSR = 0x00; // scan mode reads are setup to be left aligned in motor isr // update cached values adc_throttle = ADC1->DB7RH; // only 8bit resolution used // must read in high -> low order according to data sheet uint8_t high, low; // read torque high = ADC1->DB4RH; low = ADC1->DB4RL; adc_torque = (uint16_t)high << 2 | low; // read battery voltage high = ADC1->DB6RH; low = ADC1->DB6RL; adc_battery_voltage = (uint16_t)high << 2 | low; } } ================================================ FILE: src/firmware/tsdz2/cpu.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _TSDZ2_CPU_H_ #define _TSDZ2_CPU_H_ #define STM8S105 #define CPU_FREQ 16000000L #endif ================================================ FILE: src/firmware/tsdz2/eeprom.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "eeprom.h" #include "watchdog.h" #include "tsdz2/cpu.h" #include "stm8s/stm8s.h" #include "stm8s/stm8s_flash.h" #define EEPROM_START_ADDRESS 0x4000 static uint16_t selected_address; void eeprom_init() { selected_address = EEPROM_START_ADDRESS; } bool eeprom_select_page(int page) { if (page >= 0 && page < 2) { selected_address = EEPROM_START_ADDRESS + (page * 256); return true; } return false; } int eeprom_read_byte(int offset) { uint8_t* address = (uint8_t*)(selected_address + offset); return *address; } bool eeprom_erase_page() { return true; // not needed } bool eeprom_write_byte(int offset, uint8_t value) { uint8_t* address = (uint8_t*)(selected_address + offset); // disable flash write protection if enabled if (!(FLASH->IAPSR & FLASH_IAPSR_DUL)) { FLASH->DUKR = FLASH_RASS_KEY2; FLASH->DUKR = FLASH_RASS_KEY1; while (!(FLASH->IAPSR & FLASH_IAPSR_DUL)); } watchdog_yeild(); // :TODO: use faster api to write entire page *address = value; while (!(FLASH->IAPSR & FLASH_IAPSR_EOP)); return true; } bool eeprom_end_write() { // enable write protection FLASH->IAPSR &= ~FLASH_IAPSR_DUL; return true; } ================================================ FILE: src/firmware/tsdz2/interrupt.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _TSDZ2_INTERRUPT_H_ #define _TSDZ2_INTERRUPT_H_ #include "intellisense.h" #include "tsdz2/cpu.h" #include "tsdz2/stm8s/stm8s_itc.h" void isr_timer1_cmp(void) __interrupt(ITC_IRQ_TIM1_CAPCOM); // motor.c void isr_timer3_ovf(void) __interrupt(ITC_IRQ_TIM3_OVF); // system.c void isr_timer4_ovf(void) __interrupt(ITC_IRQ_TIM4_OVF); // sensors.c void isr_adc1(void) __interrupt(ITC_IRQ_ADC1); // adc.c void isr_uart2_rx(void) __interrupt(ITC_IRQ_UART2_RX); // uart.c void isr_uart2_tx(void) __interrupt(ITC_IRQ_UART2_TX); // uart.c #endif ================================================ FILE: src/firmware/tsdz2/lights.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "lights.h" #include "stm8.h" #include "pins.h" static bool lights_enabled; static bool lights_on; void lights_init() { SET_PIN_OUTPUT(PIN_LIGHTS); lights_enabled = false; lights_set(false); } void lights_enable() { lights_enabled = true; lights_set(lights_on); } void lights_disable() { lights_enabled = false; lights_set(lights_on); } void lights_set(bool on) { lights_on = on; if (lights_on && lights_enabled) { SET_PIN_HIGH(PIN_LIGHTS); } else { SET_PIN_LOW(PIN_LIGHTS); } } ================================================ FILE: src/firmware/tsdz2/motor.c ================================================ /* * TongSheng TSDZ2 motor controller firmware/ * * Copyright (C) Casainho, 2018. * * Released under the GPL License, Version 3 * * - Original motor control code from TongSheng TSDZ2 motor controller firmware. * - 9bit motor pwm from fork by Frans-Willem. * - Cleaned up and integrated into bbs-fw by Daniel Nilsson. */ #include #include "motor.h" #include "system.h" #include "uart.h" #include "eventlog.h" #include "util.h" #include "adc.h" #include "tsdz2/cpu.h" #include "tsdz2/timers.h" #include "tsdz2/pins.h" #include "tsdz2/stm8.h" #include "tsdz2/stm8s/stm8s.h" #include "tsdz2/stm8s/stm8s_tim1.h" #include "tsdz2/stm8s/stm8s_itc.h" #include "tsdz2/stm8s/stm8s_adc1.h" #include "tsdz2/stm8s/stm8s_flash.h" // Motor // --------------------------------------------------------------------------------- // hard current limits #define MAX_BATTERY_CURRENT_AMPS_X10 200 #define MAX_MOTOR_PHASE_CURRENT_AMPS_X10 300 // Maximum current ramp // ---------------------------------------------- // Every second has 15625 pwm cycles interrupts, // one ADC battery current step -> 0.156 amps: // // A / 0.156 = X (we need to do X steps ramp up per second) // Therefore : // 15625 / (A / 0.156) => (15625 * 0.156) / A // // 20A/s: (15625 * 0.156) / 20 = 135 #define CURRENT_RAMP_UP_INVERSE_STEP 135 // Choose PWM ramp up/down step (higher value will make the motor acceleration slower) // // For a 24V battery, 25 for ramp up seems ok. For an higher voltage battery, this values should be higher #define PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP 24 #define PWM_DUTY_CYCLE_RAMP_DOWN_INVERSE_STEP 28 // This value should be near 0. // You can try to tune with the whell on the air, full throttle and look at batttery current: adjust for lower battery current #define MOTOR_ROTOR_OFFSET_ANGLE 11 // This value is ERPS speed after which a transition happens from sinewave no interpolation to have // interpolation 60 degrees and must be found experimentally #define MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES 10 #define PWM_CYCLES_COUNTER_MAX 3125U // 5 erps minimum speed; 1/5 = 200ms; 200ms/64us = 3125 #define PWM_CYCLES_SECOND 15625U // 1 / 64us (PWM period) #define PWM_DUTY_CYCLE_MAX 254 #define PWM_DUTY_CYCLE_MIN 20 #define MOTOR_ROTOR_ANGLE_90 (63 + MOTOR_ROTOR_OFFSET_ANGLE) #define MOTOR_ROTOR_ANGLE_150 (106 + MOTOR_ROTOR_OFFSET_ANGLE) #define MOTOR_ROTOR_ANGLE_210 (148 + MOTOR_ROTOR_OFFSET_ANGLE) #define MOTOR_ROTOR_ANGLE_270 (191 + MOTOR_ROTOR_OFFSET_ANGLE) #define MOTOR_ROTOR_ANGLE_330 (233 + MOTOR_ROTOR_OFFSET_ANGLE) #define MOTOR_ROTOR_ANGLE_30 (20 + MOTOR_ROTOR_OFFSET_ANGLE) // motor maximum rotation // 700 is equal to 124 cadence, as TSDZ2 has a reduction ratio of 41.8 #define MAX_MOTOR_SPEED_ERPS 700 // Set how often the motor speed limit controller runs in the isr #define SPEED_CONTROLLER_CHECK_PERIODS 2000 // Set how oftern the current controller runs in the isr #define CURRENT_CONTROLLER_CHECK_PERIODS 14 // adc measurements // ------------------------------------------ // 10bit: 0.086V per step // 0.156A per step #define ADC_10BIT_VOLTAGE_PER_ADC_STEP_X512 44 #define ADC_10BIT_CURRENT_PER_ADC_STEP_X512 80 #define ADC_10BIT_STEPS_PER_VOLT_X512 5953 // filter coefficients #define BATTERY_CURRENT_FILTER_COEFFICIENT 2 #define PHASE_CURRENT_FILTER_COEFFICIENT 2 #define BATTERY_VOLTAGE_FILTER_COEFFICIENT 2 #define SVM_TABLE_LEN 256 #define SVM_TABLE_MIDDLE 127 #define SIN_TABLE_LEN 60 // motor states #define BLOCK_COMMUTATION 1 #define SINEWAVE_INTERPOLATION_60_DEGREES 2 // index 0-256 to degrees 0-360 // table is -90 degree preadjusted static const uint8_t svm_table[SVM_TABLE_LEN] = { 0, 11, 22, 32, 43, 54, 65, 75, 86, 96, 107, 117, 128, 138, 148, 158, 168, 178, 188, 198, 207, 217, 222, 225, 228, 230, 233, 235, 238, 240, 242, 244, 245, 247, 248, 250, 251, 252, 252, 253, 253, 254, 254, 254, 254, 254, 253, 253, 252, 251, 250, 249, 247, 246, 244, 242, 241, 238, 236, 234, 231, 229, 226, 223, 220, 223, 226, 229, 231, 234, 236, 238, 241, 242, 244, 246, 247, 249, 250, 251, 252, 253, 253, 254, 254, 254, 254, 254, 253, 253, 252, 252, 251, 250, 248, 247, 245, 244, 242, 240, 238, 235, 233, 230, 228, 225, 222, 217, 207, 198, 188, 178, 168, 158, 148, 138, 128, 117, 107, 96, 86, 75, 65, 54, 43, 32, 22, 11, 0, 11, 22, 32, 43, 54, 65, 75, 86, 96, 107, 117, 128, 138, 148, 158, 168, 178, 188, 198, 207, 217, 222, 225, 228, 230, 233, 235, 238, 240, 242, 244, 245, 247, 248, 250, 251, 252, 252, 253, 253, 254, 254, 254, 254, 254, 253, 253, 252, 251, 250, 249, 247, 246, 244, 242, 241, 238, 236, 234, 231, 229, 226, 223, 220, 223, 226, 229, 231, 234, 236, 238, 241, 242, 244, 246, 247, 249, 250, 251, 252, 253, 253, 254, 254, 254, 254, 254, 253, 253, 252, 252, 251, 250, 248, 247, 245, 244, 242, 240, 238, 235, 233, 230, 228, 225, 222, 217, 207, 198, 188, 178, 168, 158, 148, 138, 128, 117, 107, 96, 86, 75, 65, 54, 43, 32, 22, 11 }; static const uint8_t sin_table[SIN_TABLE_LEN] = { 0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 54, 57, 60, 63, 66, 68, 71, 73, 76, 78, 81, 83, 86, 88, 90, 92, 95, 97, 99, 101, 102, 104, 106, 108, 109, 111, 113, 114, 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 125, 126, 126, 127 }; // motor control state (shared with isr) // ------------------------------------------------------ #define CONTROL_STATE_DISABLE 0 #define CONTROL_STATE_PREPARE 1 #define CONTROL_STATE_START 2 #define CONTROL_STATE_RUNNING 3 static volatile uint8_t control_state = CONTROL_STATE_DISABLE; static volatile bool is_lvc_triggered = false; static volatile bool hall_sensor_error = false; // not atomic, protected by disabling interrupt while read in compute_foc_angle static volatile uint16_t speed_erps = 0; // current reading saved in 8 bits for atomic access, not expected to exceed 255 (40A) static volatile uint8_t adc_battery_current = 0; static volatile uint8_t adc_phase_current = 0; static volatile uint8_t adc_battery_target_current = 0; static volatile uint8_t foc_angle = 0; static volatile uint8_t pwm_duty_cycle = 0; static volatile uint8_t pwm_duty_cycle_target = 0; // calculated constant limits (from config) static uint16_t adc_low_voltage_limit = 0; static uint8_t adc_battery_max_current = 0; static uint8_t adc_phase_max_current = 0; // ------------------------------------------------------ // foc angle filter static uint16_t foc_angle_accumulated = 0; // battery voltage filter static uint16_t adc_battery_voltage_accumulated = 0; static uint16_t adc_battery_voltage_filtered = 0; // battery current filter static uint16_t adc_battery_current_accumulated = 0; static uint16_t adc_battery_current_filtered = 0; // motor phase current filter static uint16_t adc_phase_current_accumulated = 0; static uint16_t adc_phase_current_filtered = 0; static uint16_t lvc_x10V = 0; static uint8_t target_speed_percent = 0; static uint8_t target_current_percent = 0; static uint16_t adc_steps_per_volt_x512 = ADC_10BIT_STEPS_PER_VOLT_X512; static void flash_opt2_afr5() { // verify if PWM N channels are active on option bytes, if not, enable static const uint8_t Value = 0x20; if (OPT->OPT2 != Value) { // unlock data memory if (!(FLASH->IAPSR & FLASH_IAPSR_DUL)) { FLASH->DUKR = FLASH_RASS_KEY2; FLASH->DUKR = FLASH_RASS_KEY1; while (!(FLASH->IAPSR & FLASH_IAPSR_DUL)); } // Enable write access to option bytes FLASH->CR2 |= FLASH_CR2_OPT; FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NOPT); // program option byte and complement OPT->OPT2 = Value; OPT->NOPT2 = (uint8_t)(~Value); while (!(FLASH->IAPSR & FLASH_IAPSR_EOP)); // Disable write access to option bytes FLASH->CR2 &= (uint8_t)(~FLASH_CR2_OPT); FLASH->NCR2 |= FLASH_NCR2_NOPT; // lock data memory FLASH->IAPSR &= ~FLASH_IAPSR_DUL; } } static void read_battery_voltage() { // low pass filter the voltage readed value, to avoid possible fast spikes/noise adc_battery_voltage_accumulated -= adc_battery_voltage_accumulated >> BATTERY_VOLTAGE_FILTER_COEFFICIENT; adc_battery_voltage_accumulated += adc_get_battery_voltage(); adc_battery_voltage_filtered = adc_battery_voltage_accumulated >> BATTERY_VOLTAGE_FILTER_COEFFICIENT; is_lvc_triggered = (adc_battery_voltage_filtered < adc_low_voltage_limit); } static void read_battery_current() { // low pass filter the positive battery readed value (no regen current), to avoid possible fast spikes/noise adc_battery_current_accumulated -= adc_battery_current_accumulated >> BATTERY_CURRENT_FILTER_COEFFICIENT; adc_battery_current_accumulated += adc_battery_current; adc_battery_current_filtered = adc_battery_current_accumulated >> BATTERY_CURRENT_FILTER_COEFFICIENT; } static void read_phase_current() { // low pass filter the positive motor pahse value (no regen current), to avoid possible fast spikes/noise adc_phase_current_accumulated -= adc_phase_current_accumulated >> PHASE_CURRENT_FILTER_COEFFICIENT; adc_phase_current_accumulated += adc_phase_current; adc_phase_current_filtered = adc_phase_current_accumulated >> PHASE_CURRENT_FILTER_COEFFICIENT; } static uint8_t asin_table(uint8_t inverted_angle_x128) { // calc asin also converts the final result to degrees uint8_t index = 0; while (index < SIN_TABLE_LEN) { if (inverted_angle_x128 < sin_table[index]) { break; } index++; } // first value of table is 0 so index will always increment to at least 1 and return 0 return index--; } static void compute_foc_angle() { uint16_t ui16_temp; uint32_t ui32_temp; uint16_t e_phase_voltage; uint32_t i_phase_current_x2; uint32_t l_x1048576; uint32_t w_angular_velocity_x16; uint16_t iwl_128; // FOC implementation by calculating the angle between phase current and rotor magnetic flux (BEMF) // 1. phase voltage is calculate // 2. I*w*L is calculated, where I is the phase current. L was a measured value for 48V motor. // 3. inverse sin is calculated of (I*w*L) / phase voltage, were we obtain the angle // 4. previous calculated angle is applied to phase voltage vector angle and so the // angle between phase current and rotor magnetic flux (BEMF) is kept at 0 (max torque per amp) // calc E phase voltage ui16_temp = adc_battery_voltage_filtered * ADC_10BIT_VOLTAGE_PER_ADC_STEP_X512; ui16_temp = (ui16_temp >> 8) * pwm_duty_cycle; e_phase_voltage = ui16_temp >> 9; // calc I phase current if (pwm_duty_cycle > 10) { ui16_temp = ((uint16_t)adc_battery_current_filtered) * ADC_10BIT_CURRENT_PER_ADC_STEP_X512; i_phase_current_x2 = ui16_temp / pwm_duty_cycle; } else { i_phase_current_x2 = 0; } // calc W angular velocity: erps * 6.3 // 101 = 6.3 * 16 TIM1->IER &= ~(uint8_t)TIM1_IT_CC4; ui16_temp = speed_erps; TIM1->IER |= TIM1_IT_CC4; w_angular_velocity_x16 = ui16_temp * 101; // --------------------------------------------------------------------------------------------------------------------- // 36 V motor: L = 76uH // 48 V motor: L = 135uH // ui32_l_x1048576 = 142; // 1048576 = 2^20 | 48V // ui32_l_x1048576 = 84; // 1048576 = 2^20 | 36V // // ui32_l_x1048576 = 142 <--- THIS VALUE WAS verified experimentaly on 2018.07 to be near the best value for a 48V motor // Test done with a fixed mechanical load, duty_cycle = 200 and 100 and measured battery current was 16 and 6 (10 and 4 amps) // --------------------------------------------------------------------------------------------------------------------- #if 0 l_x1048576 = 84; // 36 V motor #else l_x1048576 = 142; // 48 V motor #endif // calc IwL ui32_temp = i_phase_current_x2 * l_x1048576; ui32_temp *= w_angular_velocity_x16; iwl_128 = ui32_temp >> 18; // calc FOC angle uint8_t foc_angle_unfiltered = asin_table(iwl_128 / e_phase_voltage); // low pass filter FOC angle foc_angle_accumulated -= foc_angle_accumulated >> 4; foc_angle_accumulated += foc_angle_unfiltered; foc_angle = foc_angle_accumulated >> 4; } void motor_pre_init() { SET_PIN_INPUT(PIN_HALL_SENSOR_A); SET_PIN_INPUT(PIN_HALL_SENSOR_B); SET_PIN_INPUT(PIN_HALL_SENSOR_C); SET_PIN_LOW(PIN_PWM_PHASE_A_LOW); SET_PIN_LOW(PIN_PWM_PHASE_A_HIGH); SET_PIN_LOW(PIN_PWM_PHASE_B_LOW); SET_PIN_LOW(PIN_PWM_PHASE_B_HIGH); SET_PIN_LOW(PIN_PWM_PHASE_C_LOW); SET_PIN_LOW(PIN_PWM_PHASE_C_HIGH); SET_PIN_OUTPUT(PIN_PWM_PHASE_A_LOW); SET_PIN_OUTPUT(PIN_PWM_PHASE_A_HIGH); SET_PIN_OUTPUT(PIN_PWM_PHASE_B_LOW); SET_PIN_OUTPUT(PIN_PWM_PHASE_B_HIGH); SET_PIN_OUTPUT(PIN_PWM_PHASE_C_LOW); SET_PIN_OUTPUT(PIN_PWM_PHASE_C_HIGH); } void motor_init(uint16_t max_current_mA, uint8_t lvc_V, int16_t adc_calib_volt_step_offset) { lvc_x10V = lvc_V * 10; uint32_t max_current_x10A = max_current_mA / 100; adc_steps_per_volt_x512 = ADC_10BIT_STEPS_PER_VOLT_X512 + adc_calib_volt_step_offset; // compute hard current limits (not changed after here) adc_battery_max_current = (uint8_t)( ((((uint32_t)MIN(max_current_x10A, MAX_BATTERY_CURRENT_AMPS_X10)) * 512) / 10) / ADC_10BIT_CURRENT_PER_ADC_STEP_X512 ); adc_phase_max_current = (uint8_t)( ((((uint32_t)MAX_MOTOR_PHASE_CURRENT_AMPS_X10) * 512) / 10) / ADC_10BIT_CURRENT_PER_ADC_STEP_X512 ); adc_low_voltage_limit = (uint16_t)((((uint32_t)lvc_V) * adc_steps_per_volt_x512) / 512); flash_opt2_afr5(); timer1_init_motor_pwm(); motor_disable(); } void motor_process() { read_battery_voltage(); read_battery_current(); read_phase_current(); compute_foc_angle(); } void motor_enable() { if (control_state == CONTROL_STATE_DISABLE) { control_state = CONTROL_STATE_PREPARE; } } void motor_disable() { control_state = CONTROL_STATE_DISABLE; } uint16_t motor_status() { static uint16_t last_status = 0; uint16_t status = 0; if (hall_sensor_error) status |= MOTOR_ERROR_HALL_SENSOR; if (is_lvc_triggered) status |= MOTOR_ERROR_LVC; if (status != last_status) { last_status = status; eventlog_write_data(EVT_DATA_MOTOR_STATUS, status); } return status; } uint8_t motor_get_target_speed() { return target_speed_percent; } uint8_t motor_get_target_current() { return target_current_percent; } void motor_set_target_speed(uint8_t percent) { if (percent > 100) { percent = 100; } if (percent != target_speed_percent) { target_speed_percent = percent; eventlog_write_data(EVT_DATA_TARGET_SPEED, percent); if (percent == 0) { pwm_duty_cycle_target = 0; } else { pwm_duty_cycle_target = (uint8_t)MAP16(percent, 1, 100, PWM_DUTY_CYCLE_MIN, PWM_DUTY_CYCLE_MAX); } } } void motor_set_target_current(uint8_t percent) { if (percent > 100) { percent = 100; } if (percent != target_current_percent) { target_current_percent = percent; eventlog_write_data(EVT_DATA_TARGET_CURRENT, percent); adc_battery_target_current = ((uint16_t)percent * adc_battery_max_current) / 100; } } int16_t motor_calibrate_battery_voltage(uint16_t actual_voltage_x100) { int16_t diff = 0; if (actual_voltage_x100 != 0) { uint16_t calibrated_adc_steps_volt_x512 = (uint16_t)(((uint32_t)adc_battery_voltage_filtered * 51200u) / actual_voltage_x100); diff = calibrated_adc_steps_volt_x512 - ADC_10BIT_STEPS_PER_VOLT_X512; adc_steps_per_volt_x512 = calibrated_adc_steps_volt_x512; } else { // reset calibration if 0 is received adc_steps_per_volt_x512 = ADC_10BIT_STEPS_PER_VOLT_X512; diff = 0; } eventlog_write_data(EVT_DATA_CALIBRATE_VOLTAGE, adc_steps_per_volt_x512); return diff; } uint16_t motor_get_battery_lvc_x10() { return lvc_x10V; } uint16_t motor_get_battery_current_x10() { return (uint16_t)((((uint32_t)adc_battery_current_filtered * 10) * ADC_10BIT_CURRENT_PER_ADC_STEP_X512) >> 9); } uint16_t motor_get_battery_voltage_x10() { return (uint16_t)(((uint32_t)adc_battery_voltage_filtered * 5120) / adc_steps_per_volt_x512); } // state variables only used by isr // --------------------------------------------- static uint8_t hall_sensors_state_last = 0; static uint8_t rotor_absolute_angle = 0; static uint8_t half_erps_flag = 0; static uint8_t commutation_type = BLOCK_COMMUTATION; static uint16_t pwm_duty_cycle_ramp_up_counter = 0; static uint16_t pwm_duty_cycle_ramp_down_counter = 0; static uint16_t pwm_cycles_counter = 1; static uint16_t pwm_cycles_counter_6 = 1; static uint16_t pwm_cycles_counter_total = 0xffff; static uint16_t adc_current_ramp_up_counter = 0; static uint8_t current_controller_counter = 0; static uint16_t speed_controller_counter = 0; static uint8_t adc_battery_ramp_max_current = 0; // Measures did with a 24V Q85 328 RPM motor, rotating motor backwards by hand: // Hall sensor A positive to negative transition | BEMF phase B at max value / top of sinewave // Hall sensor B positive to negative transition | BEMF phase A at max value / top of sinewave // Hall sensor C positive to negative transition | BEMF phase C at max value / top of sinewave // runs every 64us (PWM frequency) // Measured on 2022-12-04, the interrupt code takes about 45% of the total 64us void isr_timer1_cmp(void) __interrupt(ITC_IRQ_TIM1_CAPCOM) { // read battery current adc value, should happen at middle of the pwm duty cycle // no scan, align data right since we are only interested in the 8 lsb. ADC1->CR2 = (ADC1_ALIGN_RIGHT); // disable eoc interrupt, clear EOC flag and select channel 5 (current sense) ADC1->CSR = 0x05; // perform single mode ADC1 conversion ADC1->CR1 |= ADC1_CR1_ADON; while (!(ADC1->CSR & ADC1_CSR_EOC)); // adc current reading is truncated to 8bit since that allows a // range of up to 40A which it is not expected to be surpassed. // check of 8bit overflow and save result, flag is used to limit // current in isr if overflow for some reason would occur. uint8_t adc_battery_current_ovf = ADC1->DRH; // atomic write (uint8), current is not expected to exceed adc 255 (40A) adc_battery_current = ADC1->DRL; switch (control_state) { case CONTROL_STATE_DISABLE: // disable outputs TIM1->CCER1 &= ~(uint8_t)(TIM1_CCER1_CC1E | TIM1_CCER1_CC1NE); // OC1 TIM1->CCER1 &= ~(uint8_t)(TIM1_CCER1_CC2E | TIM1_CCER1_CC2NE); // OC2 TIM1->CCER2 &= ~(uint8_t)(TIM1_CCER2_CC3E | TIM1_CCER2_CC3NE); // OC3 break; case CONTROL_STATE_PREPARE: if (speed_erps > 0) { // Restart from duty cycle mapped from erps. // This is probably not the correct way to do this, but // it seems to work reasonably well. VESC tracks back-emf // to calculate duty cyle to restart from... pwm_duty_cycle = (uint8_t)MAP32(speed_erps, 0, MAX_MOTOR_SPEED_ERPS, PWM_DUTY_CYCLE_MIN, PWM_DUTY_CYCLE_MAX); } control_state = CONTROL_STATE_START; break; case CONTROL_STATE_START: // enable outputs TIM1->CCER1 |= (uint8_t)(TIM1_CCER1_CC1E | TIM1_CCER1_CC1NE); // OC1 TIM1->CCER1 |= (uint8_t)(TIM1_CCER1_CC2E | TIM1_CCER1_CC2NE); // OC2 TIM1->CCER2 |= (uint8_t)(TIM1_CCER2_CC3E | TIM1_CCER2_CC3NE); // OC3 control_state = CONTROL_STATE_RUNNING; break; default: break; } // calculate motor current adc value if (pwm_duty_cycle > 0) { // atomic write (uint8), current is not expected to exceed adc 255 (40A) adc_phase_current = (uint8_t)((adc_battery_current * 256u) / pwm_duty_cycle); } else { adc_phase_current = 0; } // trigger adc conversion of all channels (scan conversion, buffered) // adc scan mode conversion will finish before // this motor control interrupt will be run next time // // enable scan, align left ADC1->CR2 = (ADC1_ALIGN_LEFT | ADC1_CR2_SCAN); // clear EOC flag, enable eoc interrupt, scan read all channel 0-7 ADC1->CSR = (ADC1_CSR_EOCIE | 0x07); // start adc scan mode conversion ADC1->CR1 |= ADC1_CR1_ADON; // read hall sensor signals // find the motor rotor absolute angle // calc motor speed in erps (speed_erps) // read hall sensors signal pins and mask other pins // hall sensors sequence with motor forward rotation: 4, 6, 2, 3, 1, 5 uint8_t hall_sensors_state = ((GET_PORT(PIN_HALL_SENSOR_A)->IDR & GET_PIN(PIN_HALL_SENSOR_A)) >> 5) | ((GET_PORT(PIN_HALL_SENSOR_B)->IDR & GET_PIN(PIN_HALL_SENSOR_B)) >> 1) | ((GET_PORT(PIN_HALL_SENSOR_C)->IDR & GET_PIN(PIN_HALL_SENSOR_C)) >> 3); // make sure we run next code only when there is a change on the hall sensors signal if (hall_sensors_state != hall_sensors_state_last) { hall_sensors_state_last = hall_sensors_state; switch (hall_sensors_state) { case 3: rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_150; break; case 1: if (half_erps_flag == 1) { half_erps_flag = 0; pwm_cycles_counter_total = pwm_cycles_counter; pwm_cycles_counter = 1; if (pwm_cycles_counter_total > 0) { // This division takes 4.4us speed_erps = PWM_CYCLES_SECOND / pwm_cycles_counter_total; } else { speed_erps = PWM_CYCLES_SECOND; } // update motor commutation state based on motor speed if (speed_erps > MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES) { if (commutation_type == BLOCK_COMMUTATION) { commutation_type = SINEWAVE_INTERPOLATION_60_DEGREES; } } else { if (commutation_type == SINEWAVE_INTERPOLATION_60_DEGREES) { commutation_type = BLOCK_COMMUTATION; foc_angle = 0; } } } rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_210; break; case 5: rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_270; break; case 4: rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_330; break; case 6: half_erps_flag = 1; rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_30; break; // BEMF is always 90 degrees advanced over motor rotor position degree zero // and here (hall sensor C blue wire, signal transition from positive to negative), // phase B BEMF is at max value (measured on osciloscope by rotating the motor) case 2: rotor_absolute_angle = (uint8_t)MOTOR_ROTOR_ANGLE_90; break; default: // invalid hall sensor signal hall_sensor_error = true; return; } hall_sensor_error = false; pwm_cycles_counter_6 = 1; } // count number of fast loops / pwm cycles and reset some states when motor is near zero speed if (pwm_cycles_counter < PWM_CYCLES_COUNTER_MAX) { pwm_cycles_counter++; pwm_cycles_counter_6++; } else // happens when motor is stopped or near zero speed { pwm_cycles_counter = 1; // don't put to 0 to avoid 0 divisions pwm_cycles_counter_6 = 1; half_erps_flag = 0; speed_erps = 0; pwm_cycles_counter_total = 0xffff; foc_angle = 0; commutation_type = BLOCK_COMMUTATION; hall_sensors_state_last = 0; // this way we force execution of hall sensors code next time } // calc interpolation angle and sinewave table index uint8_t svm_table_index = rotor_absolute_angle + foc_angle; #if 1 // may be useful to disable interpolation when debugging // calculate the interpolation angle (and it doesn't work when motor starts and at very low speeds) if (commutation_type == SINEWAVE_INTERPOLATION_60_DEGREES) { // division by 0: motor_pwm_cycles_counter_total should never be 0 // TODO: verifiy if (motor_pwm_cycles_counter_6 << 8) do not overflow uint8_t interpolation_angle = (pwm_cycles_counter_6 << 8) / pwm_cycles_counter_total; // this operations take 4.4us svm_table_index += interpolation_angle; } #endif // pwm duty cycle controller // ---------------------------------------------------------------------- // brakes are active // limit battery undervoltage // limit battery max current // limit motor max erps // ramp up/down pwm duty cycle towards target ++current_controller_counter; ++speed_controller_counter; if ( control_state == CONTROL_STATE_DISABLE || is_lvc_triggered || (pwm_duty_cycle_target == 0) || (GET_PIN_INPUT_STATE(PIN_BRAKE) == 0) //active low ) { if (pwm_duty_cycle) { --pwm_duty_cycle; } } // do not control current at every PWM cycle, that will measure and control too fast. Use counter to limit else if ( current_controller_counter > CURRENT_CONTROLLER_CHECK_PERIODS && ( // check if truncated 8bit current reading did overflow adc_battery_current_ovf || // compare against ramp controller current limit adc_battery_current > adc_battery_ramp_max_current || // or hard motor phase current limit adc_phase_current > adc_phase_max_current ) ) { if (pwm_duty_cycle) { --pwm_duty_cycle; } } else if ( speed_controller_counter > SPEED_CONTROLLER_CHECK_PERIODS && // test about every 100ms speed_erps > MAX_MOTOR_SPEED_ERPS ) { if (pwm_duty_cycle) { --pwm_duty_cycle; } } else // nothing to limit, so adjust duty_cycle to duty_cycle_target { if (pwm_duty_cycle_target > pwm_duty_cycle) { if (pwm_duty_cycle_ramp_up_counter++ >= PWM_DUTY_CYCLE_RAMP_UP_INVERSE_STEP) { pwm_duty_cycle_ramp_up_counter = 0; ++pwm_duty_cycle; } } else if (pwm_duty_cycle_target < pwm_duty_cycle) { if (pwm_duty_cycle_ramp_down_counter++ >= PWM_DUTY_CYCLE_RAMP_DOWN_INVERSE_STEP) { pwm_duty_cycle_ramp_down_counter = 0; --pwm_duty_cycle; } } } // reset periodic check counters if (speed_controller_counter > SPEED_CONTROLLER_CHECK_PERIODS) { speed_controller_counter = 0; } if (current_controller_counter > CURRENT_CONTROLLER_CHECK_PERIODS) { current_controller_counter = 0; } // calculate final pwm duty cycle values to be applied to TIMER1 // The first half of the table is the positive offset from the middle (0x100), // in that case just set MSB to 0x1, and the value from the table*duty cycle to LSB. // The second half of the table is a negative offset from that same middle, // and should be substracted from 0x100. // To cheat, we leave it as 0x100 when this value * duty cycle is 0, // otherwise we assume MSB is 0, and just invert the value from the table from LSB. // Checking to see if svm_table_index >= 128 (180 degrees) by & 0x80, // as SDCC is not yet smart enough to do that automatically. #define CALC_PHASE(PHASE_OUTPUT) do { \ uint8_t tmp = ((uint16_t)(pwm_duty_cycle * svm_table[svm_table_index]) / 256); \ if (tmp > 0 && (svm_table_index & 0x80)) \ { \ PHASE_OUTPUT##_lsb = 0 - tmp; \ PHASE_OUTPUT##_msb = 0; \ } \ else \ { \ PHASE_OUTPUT##_lsb = tmp; \ PHASE_OUTPUT##_msb = 1; \ } \ } while (0) // phase B as reference phase uint8_t phase_b_voltage_msb; uint8_t phase_b_voltage_lsb; CALC_PHASE(phase_b_voltage); // phase C is advanced 120 degrees over phase B svm_table_index += 85; // 120º / 360 * 256 = 85 uint8_t phase_c_voltage_msb; uint8_t phase_c_voltage_lsb; CALC_PHASE(phase_c_voltage); // phase A is advanced 240 degrees over phase B svm_table_index += 86; // 240º / 360 * 256 = 171 - 85 already added = 86 uint8_t phase_a_voltage_msb; uint8_t phase_a_voltage_lsb; CALC_PHASE(phase_a_voltage); // set final duty cycle value to pwm timers // phase B TIM1->CCR3H = phase_b_voltage_msb; TIM1->CCR3L = phase_b_voltage_lsb; // phase C TIM1->CCR2H = phase_c_voltage_msb; TIM1->CCR2L = phase_c_voltage_lsb; // phase A TIM1->CCR1H = phase_a_voltage_msb; TIM1->CCR1L = phase_a_voltage_lsb; // ramp up motor current if (adc_battery_target_current > adc_battery_ramp_max_current) { if (adc_current_ramp_up_counter++ >= CURRENT_RAMP_UP_INVERSE_STEP) { adc_current_ramp_up_counter = 0; adc_battery_ramp_max_current++; } } else if (adc_battery_target_current < adc_battery_ramp_max_current) { // we are not doing a ramp down here, just directly setting to the target value adc_battery_ramp_max_current = adc_battery_target_current; } // clears the timer1 interrupt CC4 pending bit TIM1->SR1 = (uint8_t)(~(uint8_t)TIM1_IT_CC4); } ================================================ FILE: src/firmware/tsdz2/pins.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _TSDZ2_PINS_H_ #define _TSDZ2_PINS_H_ #include "tsdz2/cpu.h" #include "tsdz2/stm8s/stm8s.h" #include "tsdz2/stm8s/stm8s_gpio.h" #define PIN_HALL_SENSOR_A GPIOE, GPIO_PIN_5 #define PIN_HALL_SENSOR_B GPIOD, GPIO_PIN_2 #define PIN_HALL_SENSOR_C GPIOC, GPIO_PIN_5 #define PIN_PWM_PHASE_A_LOW GPIOB, GPIO_PIN_2 #define PIN_PWM_PHASE_A_HIGH GPIOC, GPIO_PIN_3 #define PIN_PWM_PHASE_B_LOW GPIOB, GPIO_PIN_1 #define PIN_PWM_PHASE_B_HIGH GPIOC, GPIO_PIN_2 #define PIN_PWM_PHASE_C_LOW GPIOB, GPIO_PIN_0 #define PIN_PWM_PHASE_C_HIGH GPIOC, GPIO_PIN_1 #define PIN_BATTERY_CURRENT GPIOB, GPIO_PIN_5 #define PIN_BATTERY_VOLTAGE GPIOB, GPIO_PIN_6 #define PIN_PAS1 GPIOD, GPIO_PIN_7 #define PIN_PAS2 GPIOE, GPIO_PIN_0 #define PIN_SPEED_SENSOR GPIOA, GPIO_PIN_1 #define PIN_BRAKE GPIOC, GPIO_PIN_6 #define PIN_THROTTLE GPIOB, GPIO_PIN_7 #define PIN_LIGHTS GPIOD, GPIO_PIN_4 #define PIN_TORQUE_SENSOR GPIOB, GPIO_PIN_3 #define PIN_TORQUE_SENSOR_EXC GPIOD, GPIO_PIN_3 #define PIN_EXTERNAL_RX GPIOD, GPIO_PIN_6 #define PIN_EXTERNAL_TX GPIOD, GPIO_PIN_5 #endif ================================================ FILE: src/firmware/tsdz2/sensors.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "sensors.h" #include "intellisense.h" #include "fwconfig.h" #include "tsdz2/interrupt.h" #include "tsdz2/timers.h" #include "tsdz2/stm8.h" #include "tsdz2/pins.h" #include "tsdz2/stm8s/stm8s_tim4.h" // interrupt runs at 100us interval, see timer4 setup in timers.c // :TODO: this file contains a lot of duplicated code from bbsx version, try to share code #define PAS_SENSOR_NUM_SIGNALS PAS_PULSES_REVOLUTION #define PAS_SENSOR_MIN_PULSE_MS_X10 50 // 500rpm limit #define SPEED_SENSOR_MIN_PULSE_MS_X10 500 #define SPEED_SENSOR_TIMEOUT_MS_X10 25000 static volatile uint16_t pas_pulse_counter; static volatile bool pas_direction_backward; static volatile uint16_t pas_period_length; // pulse length counted in interrupt frequency (100us) static uint16_t pas_period_counter; static bool pas_prev1; static bool pas_prev2; static uint16_t pas_stop_delay_periods; static volatile uint16_t speed_ticks_period_length; // pulse length counted in interrupt frequency (100us) static uint16_t speed_period_counter; static bool speed_prev_state; static uint8_t speed_ticks_per_rpm; extern void torque_sensor_init(); extern void torque_sensor_process(); void sensors_init() { pas_period_counter = 0; pas_pulse_counter = 0; pas_direction_backward = false; pas_period_length = 0; pas_stop_delay_periods = 1500; speed_period_counter = 0; speed_ticks_period_length = 0; speed_prev_state = false; speed_ticks_per_rpm = 1; // pins do not have external interrupt, use timer0 to evaluate state frequently SET_PIN_INPUT(PIN_PAS1); SET_PIN_INPUT(PIN_PAS2); SET_PIN_INPUT(PIN_SPEED_SENSOR); SET_PIN_INPUT_PULLUP(PIN_BRAKE); pas_prev1 = GET_PIN_INPUT_STATE(PIN_PAS1); pas_prev2 = GET_PIN_INPUT_STATE(PIN_PAS2); torque_sensor_init(); torque_sensor_process(); timer4_init_sensors(); } void sensors_process() { torque_sensor_process(); } void pas_set_stop_delay(uint16_t delay_ms) { pas_stop_delay_periods = delay_ms * 10; } uint16_t pas_get_cadence_rpm_x10() { uint16_t tmp; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupt tmp = pas_period_length; TIM4->IER |= TIM4_IT_UPDATE; if (tmp > 0) { return (uint16_t)((6000000ul / PAS_SENSOR_NUM_SIGNALS) / tmp); } else { return 0; } } uint16_t pas_get_pulse_counter() { uint16_t tmp; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupts tmp = pas_pulse_counter; TIM4->IER |= TIM4_IT_UPDATE; return tmp; } bool pas_is_pedaling_forwards() { uint16_t period_length; uint8_t direction_backward; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupts period_length = pas_period_length; direction_backward = pas_direction_backward; TIM4->IER |= TIM4_IT_UPDATE; // atomic read operation, no need to disable timer interrupt return period_length > 0 && !direction_backward; } bool pas_is_pedaling_backwards() { uint16_t period_length; uint8_t direction_backward; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupts period_length = pas_period_length; direction_backward = pas_direction_backward; TIM4->IER |= TIM4_IT_UPDATE; return (period_length > 0) && direction_backward; } void speed_sensor_set_signals_per_rpm(uint8_t num_signals) { speed_ticks_per_rpm = num_signals; } bool speed_sensor_is_moving() { uint16_t tmp; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupts tmp = speed_ticks_period_length; TIM4->IER |= TIM4_IT_UPDATE; return tmp > 0; } uint16_t speed_sensor_get_rpm_x10() { uint16_t tmp; TIM4->IER &= ~TIM4_IT_UPDATE; // disable timer4 interrupts tmp = speed_ticks_period_length; TIM4->IER |= TIM4_IT_UPDATE; if (tmp > 0) { return 6000000ul / tmp / speed_ticks_per_rpm; } return 0; } int16_t temperature_contr_x100() { return 0; // n/a } int16_t temperature_motor_x100() { return 0; // n/a } bool brake_is_activated() { return !GET_PIN_INPUT_STATE(PIN_BRAKE); } bool shift_sensor_is_activated() { return false; // n/a } void isr_timer4_ovf(void) __interrupt(ITC_IRQ_TIM4_OVF) { // clear interrupt bit TIM4->SR1 &= (uint8_t)(~TIM4_IT_UPDATE); // Pas { bool pas1 = GET_PIN_INPUT_STATE(PIN_PAS1); bool pas2 = GET_PIN_INPUT_STATE(PIN_PAS2); if (pas1 && !pas_prev1 /* && pas_period_counter > PAS_SENSOR_MIN_PULSE_MS_X10 */) { pas_pulse_counter++; if (pas_direction_backward != pas2) { pas_direction_backward = pas2; // Reset pas pulse counter if pedal direction is changed, // this variable counts the number of pulses since start of pedaling session. pas_pulse_counter = 0; } if (pas_period_counter > 0) { if (pas_period_counter <= pas_stop_delay_periods) { pas_period_length = pas_period_counter; // save in order to be able to calculate rpm when needed } else { pas_period_length = 0; } pas_period_counter = 0; } } else { // Do not allow wraparound or computed pedaling cadence will wrong after pedals has been still. if (pas_period_counter < 65535) { pas_period_counter++; } if (pas_period_length > 0 && pas_period_counter > pas_stop_delay_periods) { pas_period_length = 0; pas_pulse_counter = 0; pas_direction_backward = false; } } pas_prev1 = pas1; pas_prev2 = pas2; } // Speed sensor { bool spd = GET_PIN_INPUT_STATE(PIN_SPEED_SENSOR); if (spd && !speed_prev_state && speed_period_counter > SPEED_SENSOR_MIN_PULSE_MS_X10) { if (speed_period_counter <= SPEED_SENSOR_TIMEOUT_MS_X10) { speed_ticks_period_length = speed_period_counter; } else { speed_ticks_period_length = 0; } speed_period_counter = 0; } else { // Do not allow wraparound or computed speed will wrong after bike has been still. if (speed_period_counter < 65535) { speed_period_counter++; } if (speed_ticks_period_length > 0 && speed_period_counter > SPEED_SENSOR_TIMEOUT_MS_X10) { speed_ticks_period_length = 0; } } speed_prev_state = spd; } } ================================================ FILE: src/firmware/tsdz2/stm8.h ================================================ #pragma once #ifndef _TSDZ2_STM_8_H_ #define _TSDZ2_STM_8_H_ #include #define EXPAND(x) x #define SET_PIN_INPUT_(PORT, PIN) PORT->DDR &= (uint8_t)(~(PIN)); PORT->CR1 &= (uint8_t)(~(PIN)) #define SET_PIN_INPUT(...) EXPAND(SET_PIN_INPUT_(__VA_ARGS__)) #define SET_PIN_INPUT_PULLUP_(PORT, PIN) PORT->DDR &= (uint8_t)(~(PIN)); PORT->CR1 |= (uint8_t)PIN #define SET_PIN_INPUT_PULLUP(...) EXPAND(SET_PIN_INPUT_PULLUP_(__VA_ARGS__)) #define SET_PIN_OUTPUT_(PORT, PIN) PORT->DDR |= (uint8_t)PIN; PORT->CR1 |= (uint8_t)PIN; PORT->CR2 |= (uint8_t)(PIN) #define SET_PIN_OUTPUT(...) EXPAND(SET_PIN_OUTPUT_(__VA_ARGS__)) #define SET_PIN_OUTPUT_OPEN_DRAIN_(PORT, PIN) PORT->DDR |= (uint8_t)PIN; PORT->CR1 &= (uint8_t)(~(PIN)); PORT->CR2 |= (uint8_t)(PIN) #define SET_PIN_OUTPUT_OPEN_DRAIN(...) EXPAND(SET_PIN_OUTPUT_OPEN_DRAIN_(__VA_ARGS__)) #define GET_PIN_INPUT_STATE_(PORT, PIN) ((PORT->IDR & (uint8_t)PIN) != 0) #define GET_PIN_INPUT_STATE(...) EXPAND(GET_PIN_INPUT_STATE_(__VA_ARGS__)) #define SET_PIN_HIGH_(PORT, PIN) PORT->ODR |= (uint8_t)PIN #define SET_PIN_HIGH(...) EXPAND(SET_PIN_HIGH_(__VA_ARGS__)) #define SET_PIN_LOW_(PORT, PIN) PORT->ODR &= (uint8_t)(~PIN) #define SET_PIN_LOW(...) EXPAND(SET_PIN_LOW_(__VA_ARGS__)) #define TOGGLE_PIN_(PORT, PIN) PORT->ODR ^= (PIN) #define TOGGLE_PIN(...) EXPAND(TOGGLE_PIN_(__VA_ARGS__)) #define GET_PIN_(PORT, PIN) PIN #define GET_PIN(...) EXPAND(GET_PIN_(__VA_ARGS__)) #define GET_PORT_(PORT, PIN) PORT #define GET_PORT(...) EXPAND(GET_PORT_(__VA_ARGS__)) #endif ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s.h ================================================ /** ****************************************************************************** * @file stm8s.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all HW registers definitions and memory mapping. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_H #define __STM8S_H /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Uncomment the line below according to the target STM8S or STM8A device used in your application. */ /* #define STM8S208 */ /*!< STM8S High density devices with CAN */ /* #define STM8S207 */ /*!< STM8S High density devices without CAN */ /* #define STM8S007 */ /*!< STM8S Value Line High density devices */ /* #define STM8AF52Ax */ /*!< STM8A High density devices with CAN */ /* #define STM8AF62Ax */ /*!< STM8A High density devices without CAN */ /* #define STM8S105 */ /*!< STM8S Medium density devices */ /* #define STM8S005 */ /*!< STM8S Value Line Medium density devices */ /* #define STM8AF626x */ /*!< STM8A Medium density devices */ /* #define STM8AF622x */ /*!< STM8A Low density devices */ /* #define STM8S103 */ /*!< STM8S Low density devices */ /* #define STM8S003 */ /*!< STM8S Value Line Low density devices */ /* #define STM8S903 */ /*!< STM8S Low density devices */ /* #define STM8S001 */ /*!< STM8S Value Line Low denisty devices */ /* Tip: To avoid modifying this file each time you need to switch between these devices, you can define the device in your toolchain compiler preprocessor. - High-Density STM8A devices are the STM8AF52xx STM8AF6269/8x/Ax, STM8AF51xx, and STM8AF6169/7x/8x/9x/Ax microcontrollers where the Flash memory density ranges between 32 to 128 Kbytes - Medium-Density STM8A devices are the STM8AF622x/4x, STM8AF6266/68, STM8AF612x/4x, and STM8AF6166/68 microcontrollers where the Flash memory density ranges between 8 to 32 Kbytes - High-Density STM8S devices are the STM8S207xx, STM8S007 and STM8S208xx microcontrollers where the Flash memory density ranges between 32 to 128 Kbytes. - Medium-Density STM8S devices are the STM8S105x and STM8S005 microcontrollers where the Flash memory density ranges between 16 to 32-Kbytes. - Low-Density STM8A devices are the STM8AF622x microcontrollers where the Flash density is 8 Kbytes. - Low-Density STM8S devices are the STM8S103xx, STM8S003, STM8S903xx and STM8S001 microcontrollers where the Flash density is 8 Kbytes. */ #if !defined (STM8S208) && !defined (STM8S207) && !defined (STM8S105) && \ !defined (STM8S103) && !defined (STM8S903) && !defined (STM8AF52Ax) && \ !defined (STM8AF62Ax) && !defined (STM8AF626x) && !defined (STM8S007) && \ !defined (STM8S003)&& !defined (STM8S005) && !defined(STM8S001) && !defined (STM8AF622x) #error "Please select first the target STM8S/A device used in your application (in stm8s.h file)" #endif /******************************************************************************/ /* Library configuration section */ /******************************************************************************/ /* Check the used compiler */ #if defined(__CSMC__) #define _COSMIC_ #elif defined(__RCST7__) #define _RAISONANCE_ #elif defined(__ICCSTM8__) #define _IAR_ #elif defined(__SDCC) #define _SDCC_ #else #error "Unsupported Compiler!" /* Compiler defines not found */ #endif #if !defined USE_STDPERIPH_DRIVER /* Comment the line below if you will not use the peripherals drivers. In this case, these drivers will not be included and the application code will be based on direct access to peripherals registers */ // #define USE_STDPERIPH_DRIVER #endif /** * @brief In the following line adjust the value of External High Speed oscillator (HSE) used in your application Tip: To avoid modifying this file each time you need to use different HSE, you can define the HSE value in your toolchain compiler preprocessor. */ #if !defined HSE_Value #if defined (STM8S208) || defined (STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || \ defined (STM8AF62Ax) || defined (STM8AF622x) #define HSE_VALUE ((uint32_t)24000000) /* Value of the External oscillator in Hz*/ #else #define HSE_VALUE ((uint32_t)16000000) /* Value of the External oscillator in Hz*/ #endif /* STM8S208 || STM8S207 || STM8S007 || STM8AF62Ax || STM8AF52Ax || STM8AF622x */ #endif /* HSE_Value */ /** * @brief Definition of Device on-chip RC oscillator frequencies */ #define HSI_VALUE ((uint32_t)16000000) /*!< Typical Value of the HSI in Hz */ #define LSI_VALUE ((uint32_t)128000) /*!< Typical Value of the LSI in Hz */ #ifdef _COSMIC_ #define FAR @far #define NEAR @near #define TINY @tiny #define EEPROM @eeprom #define CONST const #elif defined (_RAISONANCE_) /* __RCST7__ */ #define FAR far #define NEAR data #define TINY page0 #define EEPROM eeprom #define CONST code #if defined (STM8S208) || defined (STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || \ defined (STM8AF62Ax) /*!< Used with memory Models for code higher than 64K */ #define MEMCPY fmemcpy #else /* STM8S903, STM8S103, STM8S001, STM8S003, STM8S105, STM8AF626x, STM8AF622x */ /*!< Used with memory Models for code less than 64K */ #define MEMCPY memcpy #endif /* STM8S208 or STM8S207 or STM8S007 or STM8AF62Ax or STM8AF52Ax */ #elif defined (_SDCC_) #define FAR __far #define NEAR __near #define CONST const #elif defined (_IAR_) #define FAR __far #define NEAR __near #define TINY __tiny #define EEPROM __eeprom #define CONST const #endif /* __CSMC__ */ /* For FLASH routines, select whether pointer will be declared as near (2 bytes, to handle code smaller than 64KB) or far (3 bytes, to handle code larger than 64K) */ #if defined (STM8S105) || defined (STM8S005) || defined (STM8S103) || defined (STM8S003) || \ defined (STM8S001) || defined (STM8S903) || defined (STM8AF626x) || defined (STM8AF622x) /*!< Used with memory Models for code smaller than 64K */ #define PointerAttr NEAR #define MemoryAddressCast uint16_t #else /* STM8S208 or STM8S207 or STM8AF62Ax or STM8AF52Ax */ /*!< Used with memory Models for code higher than 64K */ #define PointerAttr FAR #define MemoryAddressCast uint32_t #endif /* STM8S105 or STM8S103 or STM8S003 or STM8S001 or STM8S903 or STM8AF626x or STM8AF622x */ /* Uncomment the line below to enable the FLASH functions execution from RAM */ #if !defined (RAM_EXECUTION) /* #define RAM_EXECUTION (1) */ #endif /* RAM_EXECUTION */ #ifdef RAM_EXECUTION #ifdef _COSMIC_ #define IN_RAM(a) a #elif defined (_RAISONANCE_) /* __RCST7__ */ #define IN_RAM(a) a inram #else /*_IAR_*/ #define IN_RAM(a) __ramfunc a #endif /* _COSMIC_ */ #else #define IN_RAM(a) a #endif /* RAM_EXECUTION */ /*!< [31:16] STM8S Standard Peripheral Library main version V2.3.0*/ #define __STM8S_STDPERIPH_VERSION_MAIN ((uint8_t)0x02) /*!< [31:24] main version */ #define __STM8S_STDPERIPH_VERSION_SUB1 ((uint8_t)0x03) /*!< [23:16] sub1 version */ #define __STM8S_STDPERIPH_VERSION_SUB2 ((uint8_t)0x00) /*!< [15:8] sub2 version */ #define __STM8S_STDPERIPH_VERSION_RC ((uint8_t)0x00) /*!< [7:0] release candidate */ #define __STM8S_STDPERIPH_VERSION ( (__STM8S_STDPERIPH_VERSION_MAIN << 24)\ |(__STM8S_STDPERIPH_VERSION_SUB1 << 16)\ |(__STM8S_STDPERIPH_VERSION_SUB2 << 8)\ |(__STM8S_STDPERIPH_VERSION_RC)) /******************************************************************************/ /* Includes ------------------------------------------------------------------*/ /* Exported types and constants ----------------------------------------------*/ /** @addtogroup Exported_types * @{ */ /** * IO definitions * * define access restrictions to peripheral registers */ #define __I volatile const /*!< defines 'read only' permissions */ #define __O volatile /*!< defines 'write only' permissions */ #define __IO volatile /*!< defines 'read / write' permissions */ /*!< Integer types */ #include typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus, BitStatus, BitAction; typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; #define IS_FUNCTIONALSTATE_OK(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; #define U8_MAX (255) #define S8_MAX (127) #define S8_MIN (-128) #define U16_MAX (65535u) #define S16_MAX (32767) #define S16_MIN (-32768) #define U32_MAX (4294967295uL) #define S32_MAX (2147483647) #define S32_MIN (-2147483648uL) /** * @} */ /** @addtogroup MAP_FILE_Exported_Types_and_Constants * @{ */ /******************************************************************************/ /* IP registers structures */ /******************************************************************************/ /** * @brief General Purpose I/Os (GPIO) */ typedef struct GPIO_struct { __IO uint8_t ODR; /*!< Output Data Register */ __IO uint8_t IDR; /*!< Input Data Register */ __IO uint8_t DDR; /*!< Data Direction Register */ __IO uint8_t CR1; /*!< Configuration Register 1 */ __IO uint8_t CR2; /*!< Configuration Register 2 */ } GPIO_TypeDef; /** * @} */ /** @addtogroup GPIO_Registers_Reset_Value * @{ */ #define GPIO_ODR_RESET_VALUE ((uint8_t)0x00) #define GPIO_DDR_RESET_VALUE ((uint8_t)0x00) #define GPIO_CR1_RESET_VALUE ((uint8_t)0x00) #define GPIO_CR2_RESET_VALUE ((uint8_t)0x00) /** * @} */ /*----------------------------------------------------------------------------*/ #if defined(STM8S105) || defined(STM8S005) || defined(STM8S103) || defined(STM8S003) || \ defined(STM8S001) || defined(STM8S903) || defined(STM8AF626x) || defined(STM8AF622x) /** * @brief Analog to Digital Converter (ADC1) */ typedef struct ADC1_struct { __IO uint8_t DB0RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB0RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB1RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB1RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB2RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB2RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB3RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB3RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB4RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB4RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB5RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB5RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB6RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB6RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB7RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB7RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB8RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB8RL; /*!< ADC1 Data Buffer Register (LSB) */ __IO uint8_t DB9RH; /*!< ADC1 Data Buffer Register (MSB) */ __IO uint8_t DB9RL; /*!< ADC1 Data Buffer Register (LSB) */ uint8_t RESERVED[12]; /*!< Reserved byte */ __IO uint8_t CSR; /*!< ADC1 control status register */ __IO uint8_t CR1; /*!< ADC1 configuration register 1 */ __IO uint8_t CR2; /*!< ADC1 configuration register 2 */ __IO uint8_t CR3; /*!< ADC1 configuration register 3 */ __IO uint8_t DRH; /*!< ADC1 Data high */ __IO uint8_t DRL; /*!< ADC1 Data low */ __IO uint8_t TDRH; /*!< ADC1 Schmitt trigger disable register high */ __IO uint8_t TDRL; /*!< ADC1 Schmitt trigger disable register low */ __IO uint8_t HTRH; /*!< ADC1 high threshold register High*/ __IO uint8_t HTRL; /*!< ADC1 high threshold register Low*/ __IO uint8_t LTRH; /*!< ADC1 low threshold register high */ __IO uint8_t LTRL; /*!< ADC1 low threshold register low */ __IO uint8_t AWSRH; /*!< ADC1 watchdog status register high */ __IO uint8_t AWSRL; /*!< ADC1 watchdog status register low */ __IO uint8_t AWCRH; /*!< ADC1 watchdog control register high */ __IO uint8_t AWCRL; /*!< ADC1 watchdog control register low */ } ADC1_TypeDef; /** @addtogroup ADC1_Registers_Reset_Value * @{ */ #define ADC1_CSR_RESET_VALUE ((uint8_t)0x00) #define ADC1_CR1_RESET_VALUE ((uint8_t)0x00) #define ADC1_CR2_RESET_VALUE ((uint8_t)0x00) #define ADC1_CR3_RESET_VALUE ((uint8_t)0x00) #define ADC1_TDRL_RESET_VALUE ((uint8_t)0x00) #define ADC1_TDRH_RESET_VALUE ((uint8_t)0x00) #define ADC1_HTRL_RESET_VALUE ((uint8_t)0x03) #define ADC1_HTRH_RESET_VALUE ((uint8_t)0xFF) #define ADC1_LTRH_RESET_VALUE ((uint8_t)0x00) #define ADC1_LTRL_RESET_VALUE ((uint8_t)0x00) #define ADC1_AWCRH_RESET_VALUE ((uint8_t)0x00) #define ADC1_AWCRL_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup ADC1_Registers_Bits_Definition * @{ */ #define ADC1_CSR_EOC ((uint8_t)0x80) /*!< End of Conversion mask */ #define ADC1_CSR_AWD ((uint8_t)0x40) /*!< Analog Watch Dog Status mask */ #define ADC1_CSR_EOCIE ((uint8_t)0x20) /*!< Interrupt Enable for EOC mask */ #define ADC1_CSR_AWDIE ((uint8_t)0x10) /*!< Analog Watchdog interrupt enable mask */ #define ADC1_CSR_CH ((uint8_t)0x0F) /*!< Channel selection bits mask */ #define ADC1_CR1_SPSEL ((uint8_t)0x70) /*!< Prescaler selection mask */ #define ADC1_CR1_CONT ((uint8_t)0x02) /*!< Continuous conversion mask */ #define ADC1_CR1_ADON ((uint8_t)0x01) /*!< A/D Converter on/off mask */ #define ADC1_CR2_EXTTRIG ((uint8_t)0x40) /*!< External trigger enable mask */ #define ADC1_CR2_EXTSEL ((uint8_t)0x30) /*!< External event selection mask */ #define ADC1_CR2_ALIGN ((uint8_t)0x08) /*!< Data Alignment mask */ #define ADC1_CR2_SCAN ((uint8_t)0x02) /*!< Scan mode mask */ #define ADC1_CR3_DBUF ((uint8_t)0x80) /*!< Data Buffer Enable mask */ #define ADC1_CR3_OVR ((uint8_t)0x40) /*!< Overrun Status Flag mask */ #endif /* (STM8S105) ||(STM8S103) || (STM8S005) ||(STM8S003) || (STM8S001) || (STM8S903) || (STM8AF626x) || (STM8AF622x) */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief Analog to Digital Converter (ADC2) */ #if defined(STM8S208) || defined(STM8S207) || defined (STM8S007) || defined (STM8AF52Ax) || defined (STM8AF62Ax) typedef struct ADC2_struct { __IO uint8_t CSR; /*!< ADC2 control status register */ __IO uint8_t CR1; /*!< ADC2 configuration register 1 */ __IO uint8_t CR2; /*!< ADC2 configuration register 2 */ uint8_t RESERVED; /*!< Reserved byte */ __IO uint8_t DRH; /*!< ADC2 Data high */ __IO uint8_t DRL; /*!< ADC2 Data low */ __IO uint8_t TDRH; /*!< ADC2 Schmitt trigger disable register high */ __IO uint8_t TDRL; /*!< ADC2 Schmitt trigger disable register low */ } ADC2_TypeDef; /** @addtogroup ADC2_Registers_Reset_Value * @{ */ #define ADC2_CSR_RESET_VALUE ((uint8_t)0x00) #define ADC2_CR1_RESET_VALUE ((uint8_t)0x00) #define ADC2_CR2_RESET_VALUE ((uint8_t)0x00) #define ADC2_TDRL_RESET_VALUE ((uint8_t)0x00) #define ADC2_TDRH_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup ADC2_Registers_Bits_Definition * @{ */ #define ADC2_CSR_EOC ((uint8_t)0x80) /*!< End of Conversion mask */ #define ADC2_CSR_EOCIE ((uint8_t)0x20) /*!< Interrupt Enable for EOC mask */ #define ADC2_CSR_CH ((uint8_t)0x0F) /*!< Channel selection bits mask */ #define ADC2_CR1_SPSEL ((uint8_t)0x70) /*!< Prescaler selection mask */ #define ADC2_CR1_CONT ((uint8_t)0x02) /*!< Continuous conversion mask */ #define ADC2_CR1_ADON ((uint8_t)0x01) /*!< A/D Converter on/off mask */ #define ADC2_CR2_EXTTRIG ((uint8_t)0x40) /*!< External trigger enable mask */ #define ADC2_CR2_EXTSEL ((uint8_t)0x30) /*!< External event selection mask */ #define ADC2_CR2_ALIGN ((uint8_t)0x08) /*!< Data Alignment mask */ #endif /* (STM8S208) ||(STM8S207) || defined (STM8S007) || (STM8AF62Ax) || (STM8AF52Ax) */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief Auto Wake Up (AWU) peripheral registers. */ typedef struct AWU_struct { __IO uint8_t CSR; /*!< AWU Control status register */ __IO uint8_t APR; /*!< AWU Asynchronous prescaler buffer */ __IO uint8_t TBR; /*!< AWU Time base selection register */ } AWU_TypeDef; /** @addtogroup AWU_Registers_Reset_Value * @{ */ #define AWU_CSR_RESET_VALUE ((uint8_t)0x00) #define AWU_APR_RESET_VALUE ((uint8_t)0x3F) #define AWU_TBR_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup AWU_Registers_Bits_Definition * @{ */ #define AWU_CSR_AWUF ((uint8_t)0x20) /*!< Interrupt flag mask */ #define AWU_CSR_AWUEN ((uint8_t)0x10) /*!< Auto Wake-up enable mask */ #define AWU_CSR_MSR ((uint8_t)0x01) /*!< LSI Measurement enable mask */ #define AWU_APR_APR ((uint8_t)0x3F) /*!< Asynchronous Prescaler divider mask */ #define AWU_TBR_AWUTB ((uint8_t)0x0F) /*!< Timebase selection mask */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief Beeper (BEEP) peripheral registers. */ typedef struct BEEP_struct { __IO uint8_t CSR; /*!< BEEP Control status register */ } BEEP_TypeDef; /** @addtogroup BEEP_Registers_Reset_Value * @{ */ #define BEEP_CSR_RESET_VALUE ((uint8_t)0x1F) /** * @} */ /** @addtogroup BEEP_Registers_Bits_Definition * @{ */ #define BEEP_CSR_BEEPSEL ((uint8_t)0xC0) /*!< Beeper frequency selection mask */ #define BEEP_CSR_BEEPEN ((uint8_t)0x20) /*!< Beeper enable mask */ #define BEEP_CSR_BEEPDIV ((uint8_t)0x1F) /*!< Beeper Divider prescalar mask */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief Clock Controller (CLK) */ typedef struct CLK_struct { __IO uint8_t ICKR; /*!< Internal Clocks Control Register */ __IO uint8_t ECKR; /*!< External Clocks Control Register */ uint8_t RESERVED; /*!< Reserved byte */ __IO uint8_t CMSR; /*!< Clock Master Status Register */ __IO uint8_t SWR; /*!< Clock Master Switch Register */ __IO uint8_t SWCR; /*!< Switch Control Register */ __IO uint8_t CKDIVR; /*!< Clock Divider Register */ __IO uint8_t PCKENR1; /*!< Peripheral Clock Gating Register 1 */ __IO uint8_t CSSR; /*!< Clock Security System Register */ __IO uint8_t CCOR; /*!< Configurable Clock Output Register */ __IO uint8_t PCKENR2; /*!< Peripheral Clock Gating Register 2 */ uint8_t RESERVED1; /*!< Reserved byte */ __IO uint8_t HSITRIMR; /*!< HSI Calibration Trimmer Register */ __IO uint8_t SWIMCCR; /*!< SWIM clock control register */ } CLK_TypeDef; /** @addtogroup CLK_Registers_Reset_Value * @{ */ #define CLK_ICKR_RESET_VALUE ((uint8_t)0x01) #define CLK_ECKR_RESET_VALUE ((uint8_t)0x00) #define CLK_CMSR_RESET_VALUE ((uint8_t)0xE1) #define CLK_SWR_RESET_VALUE ((uint8_t)0xE1) #define CLK_SWCR_RESET_VALUE ((uint8_t)0x00) #define CLK_CKDIVR_RESET_VALUE ((uint8_t)0x18) #define CLK_PCKENR1_RESET_VALUE ((uint8_t)0xFF) #define CLK_PCKENR2_RESET_VALUE ((uint8_t)0xFF) #define CLK_CSSR_RESET_VALUE ((uint8_t)0x00) #define CLK_CCOR_RESET_VALUE ((uint8_t)0x00) #define CLK_HSITRIMR_RESET_VALUE ((uint8_t)0x00) #define CLK_SWIMCCR_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup CLK_Registers_Bits_Definition * @{ */ #define CLK_ICKR_SWUAH ((uint8_t)0x20) /*!< Slow Wake-up from Active Halt/Halt modes */ #define CLK_ICKR_LSIRDY ((uint8_t)0x10) /*!< Low speed internal oscillator ready */ #define CLK_ICKR_LSIEN ((uint8_t)0x08) /*!< Low speed internal RC oscillator enable */ #define CLK_ICKR_FHWU ((uint8_t)0x04) /*!< Fast Wake-up from Active Halt/Halt mode */ #define CLK_ICKR_HSIRDY ((uint8_t)0x02) /*!< High speed internal RC oscillator ready */ #define CLK_ICKR_HSIEN ((uint8_t)0x01) /*!< High speed internal RC oscillator enable */ #define CLK_ECKR_HSERDY ((uint8_t)0x02) /*!< High speed external crystal oscillator ready */ #define CLK_ECKR_HSEEN ((uint8_t)0x01) /*!< High speed external crystal oscillator enable */ #define CLK_CMSR_CKM ((uint8_t)0xFF) /*!< Clock master status bits */ #define CLK_SWR_SWI ((uint8_t)0xFF) /*!< Clock master selection bits */ #define CLK_SWCR_SWIF ((uint8_t)0x08) /*!< Clock switch interrupt flag */ #define CLK_SWCR_SWIEN ((uint8_t)0x04) /*!< Clock switch interrupt enable */ #define CLK_SWCR_SWEN ((uint8_t)0x02) /*!< Switch start/stop */ #define CLK_SWCR_SWBSY ((uint8_t)0x01) /*!< Switch busy flag*/ #define CLK_CKDIVR_HSIDIV ((uint8_t)0x18) /*!< High speed internal clock prescaler */ #define CLK_CKDIVR_CPUDIV ((uint8_t)0x07) /*!< CPU clock prescaler */ #define CLK_PCKENR1_TIM1 ((uint8_t)0x80) /*!< Timer 1 clock enable */ #define CLK_PCKENR1_TIM3 ((uint8_t)0x40) /*!< Timer 3 clock enable */ #define CLK_PCKENR1_TIM2 ((uint8_t)0x20) /*!< Timer 2 clock enable */ #define CLK_PCKENR1_TIM5 ((uint8_t)0x20) /*!< Timer 5 clock enable */ #define CLK_PCKENR1_TIM4 ((uint8_t)0x10) /*!< Timer 4 clock enable */ #define CLK_PCKENR1_TIM6 ((uint8_t)0x10) /*!< Timer 6 clock enable */ #define CLK_PCKENR1_UART3 ((uint8_t)0x08) /*!< UART3 clock enable */ #define CLK_PCKENR1_UART2 ((uint8_t)0x08) /*!< UART2 clock enable */ #define CLK_PCKENR1_UART1 ((uint8_t)0x04) /*!< UART1 clock enable */ #define CLK_PCKENR1_SPI ((uint8_t)0x02) /*!< SPI clock enable */ #define CLK_PCKENR1_I2C ((uint8_t)0x01) /*!< I2C clock enable */ #define CLK_PCKENR2_CAN ((uint8_t)0x80) /*!< CAN clock enable */ #define CLK_PCKENR2_ADC ((uint8_t)0x08) /*!< ADC clock enable */ #define CLK_PCKENR2_AWU ((uint8_t)0x04) /*!< AWU clock enable */ #define CLK_CSSR_CSSD ((uint8_t)0x08) /*!< Clock security system detection */ #define CLK_CSSR_CSSDIE ((uint8_t)0x04) /*!< Clock security system detection interrupt enable */ #define CLK_CSSR_AUX ((uint8_t)0x02) /*!< Auxiliary oscillator connected to master clock */ #define CLK_CSSR_CSSEN ((uint8_t)0x01) /*!< Clock security system enable */ #define CLK_CCOR_CCOBSY ((uint8_t)0x40) /*!< Configurable clock output busy */ #define CLK_CCOR_CCORDY ((uint8_t)0x20) /*!< Configurable clock output ready */ #define CLK_CCOR_CCOSEL ((uint8_t)0x1E) /*!< Configurable clock output selection */ #define CLK_CCOR_CCOEN ((uint8_t)0x01) /*!< Configurable clock output enable */ #define CLK_HSITRIMR_HSITRIM ((uint8_t)0x07) /*!< High speed internal oscillator trimmer */ #define CLK_SWIMCCR_SWIMDIV ((uint8_t)0x01) /*!< SWIM Clock Dividing Factor */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief 16-bit timer with complementary PWM outputs (TIM1) */ typedef struct TIM1_struct { __IO uint8_t CR1; /*!< control register 1 */ __IO uint8_t CR2; /*!< control register 2 */ __IO uint8_t SMCR; /*!< Synchro mode control register */ __IO uint8_t ETR; /*!< external trigger register */ __IO uint8_t IER; /*!< interrupt enable register*/ __IO uint8_t SR1; /*!< status register 1 */ __IO uint8_t SR2; /*!< status register 2 */ __IO uint8_t EGR; /*!< event generation register */ __IO uint8_t CCMR1; /*!< CC mode register 1 */ __IO uint8_t CCMR2; /*!< CC mode register 2 */ __IO uint8_t CCMR3; /*!< CC mode register 3 */ __IO uint8_t CCMR4; /*!< CC mode register 4 */ __IO uint8_t CCER1; /*!< CC enable register 1 */ __IO uint8_t CCER2; /*!< CC enable register 2 */ __IO uint8_t CNTRH; /*!< counter high */ __IO uint8_t CNTRL; /*!< counter low */ __IO uint8_t PSCRH; /*!< prescaler high */ __IO uint8_t PSCRL; /*!< prescaler low */ __IO uint8_t ARRH; /*!< auto-reload register high */ __IO uint8_t ARRL; /*!< auto-reload register low */ __IO uint8_t RCR; /*!< Repetition Counter register */ __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ __IO uint8_t CCR3H; /*!< capture/compare register 3 high */ __IO uint8_t CCR3L; /*!< capture/compare register 3 low */ __IO uint8_t CCR4H; /*!< capture/compare register 3 high */ __IO uint8_t CCR4L; /*!< capture/compare register 3 low */ __IO uint8_t BKR; /*!< Break Register */ __IO uint8_t DTR; /*!< dead-time register */ __IO uint8_t OISR; /*!< Output idle register */ } TIM1_TypeDef; /** @addtogroup TIM1_Registers_Reset_Value * @{ */ #define TIM1_CR1_RESET_VALUE ((uint8_t)0x00) #define TIM1_CR2_RESET_VALUE ((uint8_t)0x00) #define TIM1_SMCR_RESET_VALUE ((uint8_t)0x00) #define TIM1_ETR_RESET_VALUE ((uint8_t)0x00) #define TIM1_IER_RESET_VALUE ((uint8_t)0x00) #define TIM1_SR1_RESET_VALUE ((uint8_t)0x00) #define TIM1_SR2_RESET_VALUE ((uint8_t)0x00) #define TIM1_EGR_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCMR1_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCMR2_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCMR3_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCMR4_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCER1_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCER2_RESET_VALUE ((uint8_t)0x00) #define TIM1_CNTRH_RESET_VALUE ((uint8_t)0x00) #define TIM1_CNTRL_RESET_VALUE ((uint8_t)0x00) #define TIM1_PSCRH_RESET_VALUE ((uint8_t)0x00) #define TIM1_PSCRL_RESET_VALUE ((uint8_t)0x00) #define TIM1_ARRH_RESET_VALUE ((uint8_t)0xFF) #define TIM1_ARRL_RESET_VALUE ((uint8_t)0xFF) #define TIM1_RCR_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR1H_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR1L_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR2H_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR2L_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR3H_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR3L_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR4H_RESET_VALUE ((uint8_t)0x00) #define TIM1_CCR4L_RESET_VALUE ((uint8_t)0x00) #define TIM1_BKR_RESET_VALUE ((uint8_t)0x00) #define TIM1_DTR_RESET_VALUE ((uint8_t)0x00) #define TIM1_OISR_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup TIM1_Registers_Bits_Definition * @{ */ /* CR1*/ #define TIM1_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ #define TIM1_CR1_CMS ((uint8_t)0x60) /*!< Center-aligned Mode Selection mask. */ #define TIM1_CR1_DIR ((uint8_t)0x10) /*!< Direction mask. */ #define TIM1_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ #define TIM1_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ #define TIM1_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ #define TIM1_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ /* CR2*/ #define TIM1_CR2_TI1S ((uint8_t)0x80) /*!< TI1S Selection mask. */ #define TIM1_CR2_MMS ((uint8_t)0x70) /*!< MMS Selection mask. */ #define TIM1_CR2_COMS ((uint8_t)0x04) /*!< Capture/Compare Control Update Selection mask. */ #define TIM1_CR2_CCPC ((uint8_t)0x01) /*!< Capture/Compare Preloaded Control mask. */ /* SMCR*/ #define TIM1_SMCR_MSM ((uint8_t)0x80) /*!< Master/Slave Mode mask. */ #define TIM1_SMCR_TS ((uint8_t)0x70) /*!< Trigger Selection mask. */ #define TIM1_SMCR_SMS ((uint8_t)0x07) /*!< Slave Mode Selection mask. */ /*ETR*/ #define TIM1_ETR_ETP ((uint8_t)0x80) /*!< External Trigger Polarity mask. */ #define TIM1_ETR_ECE ((uint8_t)0x40)/*!< External Clock mask. */ #define TIM1_ETR_ETPS ((uint8_t)0x30) /*!< External Trigger Prescaler mask. */ #define TIM1_ETR_ETF ((uint8_t)0x0F) /*!< External Trigger Filter mask. */ /*IER*/ #define TIM1_IER_BIE ((uint8_t)0x80) /*!< Break Interrupt Enable mask. */ #define TIM1_IER_TIE ((uint8_t)0x40) /*!< Trigger Interrupt Enable mask. */ #define TIM1_IER_COMIE ((uint8_t)0x20) /*!< Commutation Interrupt Enable mask.*/ #define TIM1_IER_CC4IE ((uint8_t)0x10) /*!< Capture/Compare 4 Interrupt Enable mask. */ #define TIM1_IER_CC3IE ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Enable mask. */ #define TIM1_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ #define TIM1_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ #define TIM1_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ /*SR1*/ #define TIM1_SR1_BIF ((uint8_t)0x80) /*!< Break Interrupt Flag mask. */ #define TIM1_SR1_TIF ((uint8_t)0x40) /*!< Trigger Interrupt Flag mask. */ #define TIM1_SR1_COMIF ((uint8_t)0x20) /*!< Commutation Interrupt Flag mask. */ #define TIM1_SR1_CC4IF ((uint8_t)0x10) /*!< Capture/Compare 4 Interrupt Flag mask. */ #define TIM1_SR1_CC3IF ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Flag mask. */ #define TIM1_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ #define TIM1_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ #define TIM1_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ /*SR2*/ #define TIM1_SR2_CC4OF ((uint8_t)0x10) /*!< Capture/Compare 4 Overcapture Flag mask. */ #define TIM1_SR2_CC3OF ((uint8_t)0x08) /*!< Capture/Compare 3 Overcapture Flag mask. */ #define TIM1_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ #define TIM1_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ /*EGR*/ #define TIM1_EGR_BG ((uint8_t)0x80) /*!< Break Generation mask. */ #define TIM1_EGR_TG ((uint8_t)0x40) /*!< Trigger Generation mask. */ #define TIM1_EGR_COMG ((uint8_t)0x20) /*!< Capture/Compare Control Update Generation mask. */ #define TIM1_EGR_CC4G ((uint8_t)0x10) /*!< Capture/Compare 4 Generation mask. */ #define TIM1_EGR_CC3G ((uint8_t)0x08) /*!< Capture/Compare 3 Generation mask. */ #define TIM1_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ #define TIM1_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ #define TIM1_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ /*CCMR*/ #define TIM1_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ #define TIM1_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ #define TIM1_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ #define TIM1_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ #define TIM1_CCMR_OCxFE ((uint8_t)0x04) /*!< Output Compare x Fast Enable mask. */ #define TIM1_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ #define CCMR_TIxDirect_Set ((uint8_t)0x01) /*CCER1*/ #define TIM1_CCER1_CC2NP ((uint8_t)0x80) /*!< Capture/Compare 2 Complementary output Polarity mask. */ #define TIM1_CCER1_CC2NE ((uint8_t)0x40) /*!< Capture/Compare 2 Complementary output enable mask. */ #define TIM1_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ #define TIM1_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ #define TIM1_CCER1_CC1NP ((uint8_t)0x08) /*!< Capture/Compare 1 Complementary output Polarity mask. */ #define TIM1_CCER1_CC1NE ((uint8_t)0x04) /*!< Capture/Compare 1 Complementary output enable mask. */ #define TIM1_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ #define TIM1_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ /*CCER2*/ #define TIM1_CCER2_CC4P ((uint8_t)0x20) /*!< Capture/Compare 4 output Polarity mask. */ #define TIM1_CCER2_CC4E ((uint8_t)0x10) /*!< Capture/Compare 4 output enable mask. */ #define TIM1_CCER2_CC3NP ((uint8_t)0x08) /*!< Capture/Compare 3 Complementary output Polarity mask. */ #define TIM1_CCER2_CC3NE ((uint8_t)0x04) /*!< Capture/Compare 3 Complementary output enable mask. */ #define TIM1_CCER2_CC3P ((uint8_t)0x02) /*!< Capture/Compare 3 output Polarity mask. */ #define TIM1_CCER2_CC3E ((uint8_t)0x01) /*!< Capture/Compare 3 output enable mask. */ /*CNTRH*/ #define TIM1_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ /*CNTRL*/ #define TIM1_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ /*PSCH*/ #define TIM1_PSCH_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ /*PSCL*/ #define TIM1_PSCL_PSC ((uint8_t)0xFF) /*!< Prescaler Value (LSB) mask. */ /*ARR*/ #define TIM1_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ #define TIM1_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ /*RCR*/ #define TIM1_RCR_REP ((uint8_t)0xFF) /*!< Repetition Counter Value mask. */ /*CCR1*/ #define TIM1_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ #define TIM1_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ /*CCR2*/ #define TIM1_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ #define TIM1_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ /*CCR3*/ #define TIM1_CCR3H_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (MSB) mask. */ #define TIM1_CCR3L_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (LSB) mask. */ /*CCR4*/ #define TIM1_CCR4H_CCR4 ((uint8_t)0xFF) /*!< Capture/Compare 4 Value (MSB) mask. */ #define TIM1_CCR4L_CCR4 ((uint8_t)0xFF) /*!< Capture/Compare 4 Value (LSB) mask. */ /*BKR*/ #define TIM1_BKR_MOE ((uint8_t)0x80) /*!< Main Output Enable mask. */ #define TIM1_BKR_AOE ((uint8_t)0x40) /*!< Automatic Output Enable mask. */ #define TIM1_BKR_BKP ((uint8_t)0x20) /*!< Break Polarity mask. */ #define TIM1_BKR_BKE ((uint8_t)0x10) /*!< Break Enable mask. */ #define TIM1_BKR_OSSR ((uint8_t)0x08) /*!< Off-State Selection for Run mode mask. */ #define TIM1_BKR_OSSI ((uint8_t)0x04) /*!< Off-State Selection for Idle mode mask. */ #define TIM1_BKR_LOCK ((uint8_t)0x03) /*!< Lock Configuration mask. */ /*DTR*/ #define TIM1_DTR_DTG ((uint8_t)0xFF) /*!< Dead-Time Generator set-up mask. */ /*OISR*/ #define TIM1_OISR_OIS4 ((uint8_t)0x40) /*!< Output Idle state 4 (OC4 output) mask. */ #define TIM1_OISR_OIS3N ((uint8_t)0x20) /*!< Output Idle state 3 (OC3N output) mask. */ #define TIM1_OISR_OIS3 ((uint8_t)0x10) /*!< Output Idle state 3 (OC3 output) mask. */ #define TIM1_OISR_OIS2N ((uint8_t)0x08) /*!< Output Idle state 2 (OC2N output) mask. */ #define TIM1_OISR_OIS2 ((uint8_t)0x04) /*!< Output Idle state 2 (OC2 output) mask. */ #define TIM1_OISR_OIS1N ((uint8_t)0x02) /*!< Output Idle state 1 (OC1N output) mask. */ #define TIM1_OISR_OIS1 ((uint8_t)0x01) /*!< Output Idle state 1 (OC1 output) mask. */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief 16-bit timer (TIM2) */ typedef struct TIM2_struct { __IO uint8_t CR1; /*!< control register 1 */ #if defined(STM8S103) || defined(STM8S003) || defined(STM8S001) uint8_t RESERVED1; /*!< Reserved register */ uint8_t RESERVED2; /*!< Reserved register */ #endif __IO uint8_t IER; /*!< interrupt enable register */ __IO uint8_t SR1; /*!< status register 1 */ __IO uint8_t SR2; /*!< status register 2 */ __IO uint8_t EGR; /*!< event generation register */ __IO uint8_t CCMR1; /*!< CC mode register 1 */ __IO uint8_t CCMR2; /*!< CC mode register 2 */ __IO uint8_t CCMR3; /*!< CC mode register 3 */ __IO uint8_t CCER1; /*!< CC enable register 1 */ __IO uint8_t CCER2; /*!< CC enable register 2 */ __IO uint8_t CNTRH; /*!< counter high */ __IO uint8_t CNTRL; /*!< counter low */ __IO uint8_t PSCR; /*!< prescaler register */ __IO uint8_t ARRH; /*!< auto-reload register high */ __IO uint8_t ARRL; /*!< auto-reload register low */ __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ __IO uint8_t CCR3H; /*!< capture/compare register 3 high */ __IO uint8_t CCR3L; /*!< capture/compare register 3 low */ } TIM2_TypeDef; /** @addtogroup TIM2_Registers_Reset_Value * @{ */ #define TIM2_CR1_RESET_VALUE ((uint8_t)0x00) #define TIM2_IER_RESET_VALUE ((uint8_t)0x00) #define TIM2_SR1_RESET_VALUE ((uint8_t)0x00) #define TIM2_SR2_RESET_VALUE ((uint8_t)0x00) #define TIM2_EGR_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCMR1_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCMR2_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCMR3_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCER1_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCER2_RESET_VALUE ((uint8_t)0x00) #define TIM2_CNTRH_RESET_VALUE ((uint8_t)0x00) #define TIM2_CNTRL_RESET_VALUE ((uint8_t)0x00) #define TIM2_PSCR_RESET_VALUE ((uint8_t)0x00) #define TIM2_ARRH_RESET_VALUE ((uint8_t)0xFF) #define TIM2_ARRL_RESET_VALUE ((uint8_t)0xFF) #define TIM2_CCR1H_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCR1L_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCR2H_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCR2L_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCR3H_RESET_VALUE ((uint8_t)0x00) #define TIM2_CCR3L_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup TIM2_Registers_Bits_Definition * @{ */ /*CR1*/ #define TIM2_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ #define TIM2_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ #define TIM2_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ #define TIM2_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ #define TIM2_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ /*IER*/ #define TIM2_IER_CC3IE ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Enable mask. */ #define TIM2_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ #define TIM2_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ #define TIM2_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ /*SR1*/ #define TIM2_SR1_CC3IF ((uint8_t)0x08) /*!< Capture/Compare 3 Interrupt Flag mask. */ #define TIM2_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ #define TIM2_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ #define TIM2_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ /*SR2*/ #define TIM2_SR2_CC3OF ((uint8_t)0x08) /*!< Capture/Compare 3 Overcapture Flag mask. */ #define TIM2_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ #define TIM2_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ /*EGR*/ #define TIM2_EGR_CC3G ((uint8_t)0x08) /*!< Capture/Compare 3 Generation mask. */ #define TIM2_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ #define TIM2_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ #define TIM2_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ /*CCMR*/ #define TIM2_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ #define TIM2_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ #define TIM2_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ #define TIM2_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ #define TIM2_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ /*CCER1*/ #define TIM2_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ #define TIM2_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ #define TIM2_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ #define TIM2_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ /*CCER2*/ #define TIM2_CCER2_CC3P ((uint8_t)0x02) /*!< Capture/Compare 3 output Polarity mask. */ #define TIM2_CCER2_CC3E ((uint8_t)0x01) /*!< Capture/Compare 3 output enable mask. */ /*CNTR*/ #define TIM2_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ #define TIM2_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ /*PSCR*/ #define TIM2_PSCR_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ /*ARR*/ #define TIM2_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ #define TIM2_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ /*CCR1*/ #define TIM2_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ #define TIM2_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ /*CCR2*/ #define TIM2_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ #define TIM2_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ /*CCR3*/ #define TIM2_CCR3H_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (MSB) mask. */ #define TIM2_CCR3L_CCR3 ((uint8_t)0xFF) /*!< Capture/Compare 3 Value (LSB) mask. */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief 16-bit timer (TIM3) */ typedef struct TIM3_struct { __IO uint8_t CR1; /*!< control register 1 */ __IO uint8_t IER; /*!< interrupt enable register */ __IO uint8_t SR1; /*!< status register 1 */ __IO uint8_t SR2; /*!< status register 2 */ __IO uint8_t EGR; /*!< event generation register */ __IO uint8_t CCMR1; /*!< CC mode register 1 */ __IO uint8_t CCMR2; /*!< CC mode register 2 */ __IO uint8_t CCER1; /*!< CC enable register 1 */ __IO uint8_t CNTRH; /*!< counter high */ __IO uint8_t CNTRL; /*!< counter low */ __IO uint8_t PSCR; /*!< prescaler register */ __IO uint8_t ARRH; /*!< auto-reload register high */ __IO uint8_t ARRL; /*!< auto-reload register low */ __IO uint8_t CCR1H; /*!< capture/compare register 1 high */ __IO uint8_t CCR1L; /*!< capture/compare register 1 low */ __IO uint8_t CCR2H; /*!< capture/compare register 2 high */ __IO uint8_t CCR2L; /*!< capture/compare register 2 low */ } TIM3_TypeDef; /** @addtogroup TIM3_Registers_Reset_Value * @{ */ #define TIM3_CR1_RESET_VALUE ((uint8_t)0x00) #define TIM3_IER_RESET_VALUE ((uint8_t)0x00) #define TIM3_SR1_RESET_VALUE ((uint8_t)0x00) #define TIM3_SR2_RESET_VALUE ((uint8_t)0x00) #define TIM3_EGR_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCMR1_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCMR2_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCER1_RESET_VALUE ((uint8_t)0x00) #define TIM3_CNTRH_RESET_VALUE ((uint8_t)0x00) #define TIM3_CNTRL_RESET_VALUE ((uint8_t)0x00) #define TIM3_PSCR_RESET_VALUE ((uint8_t)0x00) #define TIM3_ARRH_RESET_VALUE ((uint8_t)0xFF) #define TIM3_ARRL_RESET_VALUE ((uint8_t)0xFF) #define TIM3_CCR1H_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCR1L_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCR2H_RESET_VALUE ((uint8_t)0x00) #define TIM3_CCR2L_RESET_VALUE ((uint8_t)0x00) /** * @} */ /** @addtogroup TIM3_Registers_Bits_Definition * @{ */ /*CR1*/ #define TIM3_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ #define TIM3_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ #define TIM3_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ #define TIM3_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ #define TIM3_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ /*IER*/ #define TIM3_IER_CC2IE ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Enable mask. */ #define TIM3_IER_CC1IE ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Enable mask. */ #define TIM3_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ /*SR1*/ #define TIM3_SR1_CC2IF ((uint8_t)0x04) /*!< Capture/Compare 2 Interrupt Flag mask. */ #define TIM3_SR1_CC1IF ((uint8_t)0x02) /*!< Capture/Compare 1 Interrupt Flag mask. */ #define TIM3_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ /*SR2*/ #define TIM3_SR2_CC2OF ((uint8_t)0x04) /*!< Capture/Compare 2 Overcapture Flag mask. */ #define TIM3_SR2_CC1OF ((uint8_t)0x02) /*!< Capture/Compare 1 Overcapture Flag mask. */ /*EGR*/ #define TIM3_EGR_CC2G ((uint8_t)0x04) /*!< Capture/Compare 2 Generation mask. */ #define TIM3_EGR_CC1G ((uint8_t)0x02) /*!< Capture/Compare 1 Generation mask. */ #define TIM3_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ /*CCMR*/ #define TIM3_CCMR_ICxPSC ((uint8_t)0x0C) /*!< Input Capture x Prescaler mask. */ #define TIM3_CCMR_ICxF ((uint8_t)0xF0) /*!< Input Capture x Filter mask. */ #define TIM3_CCMR_OCM ((uint8_t)0x70) /*!< Output Compare x Mode mask. */ #define TIM3_CCMR_OCxPE ((uint8_t)0x08) /*!< Output Compare x Preload Enable mask. */ #define TIM3_CCMR_CCxS ((uint8_t)0x03) /*!< Capture/Compare x Selection mask. */ /*CCER1*/ #define TIM3_CCER1_CC2P ((uint8_t)0x20) /*!< Capture/Compare 2 output Polarity mask. */ #define TIM3_CCER1_CC2E ((uint8_t)0x10) /*!< Capture/Compare 2 output enable mask. */ #define TIM3_CCER1_CC1P ((uint8_t)0x02) /*!< Capture/Compare 1 output Polarity mask. */ #define TIM3_CCER1_CC1E ((uint8_t)0x01) /*!< Capture/Compare 1 output enable mask. */ /*CNTR*/ #define TIM3_CNTRH_CNT ((uint8_t)0xFF) /*!< Counter Value (MSB) mask. */ #define TIM3_CNTRL_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ /*PSCR*/ #define TIM3_PSCR_PSC ((uint8_t)0xFF) /*!< Prescaler Value (MSB) mask. */ /*ARR*/ #define TIM3_ARRH_ARR ((uint8_t)0xFF) /*!< Autoreload Value (MSB) mask. */ #define TIM3_ARRL_ARR ((uint8_t)0xFF) /*!< Autoreload Value (LSB) mask. */ /*CCR1*/ #define TIM3_CCR1H_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (MSB) mask. */ #define TIM3_CCR1L_CCR1 ((uint8_t)0xFF) /*!< Capture/Compare 1 Value (LSB) mask. */ /*CCR2*/ #define TIM3_CCR2H_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (MSB) mask. */ #define TIM3_CCR2L_CCR2 ((uint8_t)0xFF) /*!< Capture/Compare 2 Value (LSB) mask. */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief 8-bit system timer (TIM4) */ typedef struct TIM4_struct { __IO uint8_t CR1; /*!< control register 1 */ #if defined(STM8S103) || defined(STM8S003) || defined(STM8S001) uint8_t RESERVED1; /*!< Reserved register */ uint8_t RESERVED2; /*!< Reserved register */ #endif __IO uint8_t IER; /*!< interrupt enable register */ __IO uint8_t SR1; /*!< status register 1 */ __IO uint8_t EGR; /*!< event generation register */ __IO uint8_t CNTR; /*!< counter register */ __IO uint8_t PSCR; /*!< prescaler register */ __IO uint8_t ARR; /*!< auto-reload register */ } TIM4_TypeDef; /** @addtogroup TIM4_Registers_Reset_Value * @{ */ #define TIM4_CR1_RESET_VALUE ((uint8_t)0x00) #define TIM4_IER_RESET_VALUE ((uint8_t)0x00) #define TIM4_SR1_RESET_VALUE ((uint8_t)0x00) #define TIM4_EGR_RESET_VALUE ((uint8_t)0x00) #define TIM4_CNTR_RESET_VALUE ((uint8_t)0x00) #define TIM4_PSCR_RESET_VALUE ((uint8_t)0x00) #define TIM4_ARR_RESET_VALUE ((uint8_t)0xFF) /** * @} */ /** @addtogroup TIM4_Registers_Bits_Definition * @{ */ /*CR1*/ #define TIM4_CR1_ARPE ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */ #define TIM4_CR1_OPM ((uint8_t)0x08) /*!< One Pulse Mode mask. */ #define TIM4_CR1_URS ((uint8_t)0x04) /*!< Update Request Source mask. */ #define TIM4_CR1_UDIS ((uint8_t)0x02) /*!< Update DIsable mask. */ #define TIM4_CR1_CEN ((uint8_t)0x01) /*!< Counter Enable mask. */ /*IER*/ #define TIM4_IER_UIE ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */ /*SR1*/ #define TIM4_SR1_UIF ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */ /*EGR*/ #define TIM4_EGR_UG ((uint8_t)0x01) /*!< Update Generation mask. */ /*CNTR*/ #define TIM4_CNTR_CNT ((uint8_t)0xFF) /*!< Counter Value (LSB) mask. */ /*PSCR*/ #define TIM4_PSCR_PSC ((uint8_t)0x07) /*!< Prescaler Value mask. */ /*ARR*/ #define TIM4_ARR_ARR ((uint8_t)0xFF) /*!< Autoreload Value mask. */ /** * @} */ /*----------------------------------------------------------------------------*/ /** * @brief 16-bit timer with synchro module (TIM5) */ typedef struct TIM5_struct { __IO uint8_t CR1; /*! #define enableInterrupts() _rim_() /* enable interrupts */ #define disableInterrupts() _sim_() /* disable interrupts */ #define rim() _rim_() /* enable interrupts */ #define sim() _sim_() /* disable interrupts */ #define nop() _nop_() /* No Operation */ #define trap() _trap_() /* Trap (soft IT) */ #define wfi() _wfi_() /* Wait For Interrupt */ #define halt() _halt_() /* Halt */ #elif defined(_COSMIC_) #define enableInterrupts() {_asm("rim\n");} /* enable interrupts */ #define disableInterrupts() {_asm("sim\n");} /* disable interrupts */ #define rim() {_asm("rim\n");} /* enable interrupts */ #define sim() {_asm("sim\n");} /* disable interrupts */ #define nop() {_asm("nop\n");} /* No Operation */ #define trap() {_asm("trap\n");} /* Trap (soft IT) */ #define wfi() {_asm("wfi\n");} /* Wait For Interrupt */ #define halt() {_asm("halt\n");} /* Halt */ #elif defined(_IAR_) #include #define enableInterrupts() __enable_interrupt() /* enable interrupts */ #define disableInterrupts() __disable_interrupt() /* disable interrupts */ #define rim() __enable_interrupt() /* enable interrupts */ #define sim() __disable_interrupt() /* disable interrupts */ #define nop() __no_operation() /* No Operation */ #define trap() __trap() /* Trap (soft IT) */ #define wfi() __wait_for_interrupt() /* Wait For Interrupt */ #define halt() __halt() /* Halt */ #elif defined(_SDCC_) #define enableInterrupts() \ do { \ __asm__("rim"); \ } while (0) /* enable interrupts */ #define disableInterrupts() \ do { \ __asm__("sim"); \ } while (0) /* disable interrupts */ #define rim() \ do { \ __asm__("rim"); \ } while (0) /* enable interrupts */ #define sim() \ do { \ __asm__("sim"); \ } while (0) /* disable interrupts */ #define nop() \ do { \ __asm__("nop"); \ } while (0) /* No Operation */ #define trap() \ do { \ __asm__("trap"); \ } while (0) /* Trap (soft IT) */ #define wfi() \ do { \ __asm__("wfi"); \ } while (0) /* Wait For Interrupt */ #define halt() \ do { \ __asm__("halt"); \ } while (0) /* Halt */ #endif /*_RAISONANCE_*/ /*============================== Interrupt vector Handling ========================*/ #ifdef _COSMIC_ #define INTERRUPT_HANDLER(a,b) @far @interrupt void a(void) #define INTERRUPT_HANDLER_TRAP(a) void @far @interrupt a(void) #endif /* _COSMIC_ */ #ifdef _RAISONANCE_ #define INTERRUPT_HANDLER(a,b) void a(void) interrupt b #define INTERRUPT_HANDLER_TRAP(a) void a(void) trap #endif /* _RAISONANCE_ */ #ifdef _IAR_ #define STRINGVECTOR(x) #x #define VECTOR_ID(x) STRINGVECTOR( vector = (x) ) #define INTERRUPT_HANDLER( a, b ) \ _Pragma( VECTOR_ID( (b)+2 ) ) \ __interrupt void (a)( void ) #define INTERRUPT_HANDLER_TRAP(a) \ _Pragma( VECTOR_ID( 1 ) ) \ __interrupt void (a) (void) #endif /* _IAR_ */ #ifdef _SDCC_ #define INTERRUPT_HANDLER(a,b) void a() __interrupt(b) #define INTERRUPT_HANDLER_TRAP(a) void a() __trap #endif /* _SDCC_ */ /*============================== Interrupt Handler declaration ========================*/ #ifdef _COSMIC_ #define INTERRUPT @far @interrupt #elif defined(_IAR_) #define INTERRUPT __interrupt #endif /* _COSMIC_ */ /*============================== Handling bits ====================================*/ /*----------------------------------------------------------------------------- Method : I Description : Handle the bit from the character variables. Comments : The different parameters of commands are - VAR : Name of the character variable where the bit is located. - Place : Bit position in the variable (7 6 5 4 3 2 1 0) - Value : Can be 0 (reset bit) or not 0 (set bit) The "MskBit" command allows to select some bits in a source variables and copy it in a destination var (return the value). The "ValBit" command returns the value of a bit in a char variable: the bit is reset if it returns 0 else the bit is set. This method generates not an optimised code yet. -----------------------------------------------------------------------------*/ #define SetBit(VAR,Place) ( (VAR) |= (uint8_t)((uint8_t)1<<(uint8_t)(Place)) ) #define ClrBit(VAR,Place) ( (VAR) &= (uint8_t)((uint8_t)((uint8_t)1<<(uint8_t)(Place))^(uint8_t)255) ) #define ChgBit(VAR,Place) ( (VAR) ^= (uint8_t)((uint8_t)1<<(uint8_t)(Place)) ) #define AffBit(VAR,Place,Value) ((Value) ? \ ((VAR) |= ((uint8_t)1<<(Place))) : \ ((VAR) &= (((uint8_t)1<<(Place))^(uint8_t)255))) #define MskBit(Dest,Msk,Src) ( (Dest) = ((Msk) & (Src)) | ((~(Msk)) & (Dest)) ) #define ValBit(VAR,Place) ((uint8_t)(VAR) & (uint8_t)((uint8_t)1<<(uint8_t)(Place))) #define BYTE_0(n) ((uint8_t)((n) & (uint8_t)0xFF)) /*!< Returns the low byte of the 32-bit value */ #define BYTE_1(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)8))) /*!< Returns the second byte of the 32-bit value */ #define BYTE_2(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)16))) /*!< Returns the third byte of the 32-bit value */ #define BYTE_3(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)24))) /*!< Returns the high byte of the 32-bit value */ #define UNUSED(x) ((void)(x)) /*============================== Assert Macros ====================================*/ #define IS_STATE_VALUE_OK(SensitivityValue) \ (((SensitivityValue) == ENABLE) || \ ((SensitivityValue) == DISABLE)) /*----------------------------------------------------------------------------- Method : II Description : Handle directly the bit. Comments : The idea is to handle directly with the bit name. For that, it is necessary to have RAM area descriptions (example: HW register...) and the following command line for each area. This method generates the most optimized code. -----------------------------------------------------------------------------*/ #define AREA 0x00 /* The area of bits begins at address 0x10. */ #define BitClr(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) &= (~(1<<(7-(BIT)%8))) ) #define BitSet(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) |= (1<<(7-(BIT)%8)) ) #define BitVal(BIT) ( *((unsigned char *) (AREA+(BIT)/8)) & (1<<(7-(BIT)%8)) ) /* Exported functions ------------------------------------------------------- */ #endif /* __STM8S_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_adc1.h ================================================ /** ****************************************************************************** * @file stm8s_adc1.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all the prototypes/macros for the ADC1 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_ADC1_H #define __STM8S_ADC1_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup ADC1_Exported_Types * @{ */ /** * @brief ADC1 clock prescaler selection */ typedef enum { ADC1_PRESSEL_FCPU_D2 = (uint8_t)0x00, /**< Prescaler selection fADC1 = fcpu/2 */ ADC1_PRESSEL_FCPU_D3 = (uint8_t)0x10, /**< Prescaler selection fADC1 = fcpu/3 */ ADC1_PRESSEL_FCPU_D4 = (uint8_t)0x20, /**< Prescaler selection fADC1 = fcpu/4 */ ADC1_PRESSEL_FCPU_D6 = (uint8_t)0x30, /**< Prescaler selection fADC1 = fcpu/6 */ ADC1_PRESSEL_FCPU_D8 = (uint8_t)0x40, /**< Prescaler selection fADC1 = fcpu/8 */ ADC1_PRESSEL_FCPU_D10 = (uint8_t)0x50, /**< Prescaler selection fADC1 = fcpu/10 */ ADC1_PRESSEL_FCPU_D12 = (uint8_t)0x60, /**< Prescaler selection fADC1 = fcpu/12 */ ADC1_PRESSEL_FCPU_D18 = (uint8_t)0x70 /**< Prescaler selection fADC1 = fcpu/18 */ } ADC1_PresSel_TypeDef; /** * @brief ADC1 External conversion trigger event selection */ typedef enum { ADC1_EXTTRIG_TIM = (uint8_t)0x00, /**< Conversion from Internal TIM1 TRGO event */ ADC1_EXTTRIG_GPIO = (uint8_t)0x10 /**< Conversion from External interrupt on ADC_ETR pin*/ } ADC1_ExtTrig_TypeDef; /** * @brief ADC1 data alignment */ typedef enum { ADC1_ALIGN_LEFT = (uint8_t)0x00, /**< Data alignment left */ ADC1_ALIGN_RIGHT = (uint8_t)0x08 /**< Data alignment right */ } ADC1_Align_TypeDef; /** * @brief ADC1 Interrupt source */ typedef enum { ADC1_IT_AWDIE = (uint16_t)0x010, /**< Analog WDG interrupt enable */ ADC1_IT_EOCIE = (uint16_t)0x020, /**< EOC interrupt enable */ ADC1_IT_AWD = (uint16_t)0x140, /**< Analog WDG status */ ADC1_IT_AWS0 = (uint16_t)0x110, /**< Analog channel 0 status */ ADC1_IT_AWS1 = (uint16_t)0x111, /**< Analog channel 1 status */ ADC1_IT_AWS2 = (uint16_t)0x112, /**< Analog channel 2 status */ ADC1_IT_AWS3 = (uint16_t)0x113, /**< Analog channel 3 status */ ADC1_IT_AWS4 = (uint16_t)0x114, /**< Analog channel 4 status */ ADC1_IT_AWS5 = (uint16_t)0x115, /**< Analog channel 5 status */ ADC1_IT_AWS6 = (uint16_t)0x116, /**< Analog channel 6 status */ ADC1_IT_AWS7 = (uint16_t)0x117, /**< Analog channel 7 status */ ADC1_IT_AWS8 = (uint16_t)0x118, /**< Analog channel 8 status */ ADC1_IT_AWS9 = (uint16_t)0x119, /**< Analog channel 9 status */ ADC1_IT_AWS12 = (uint16_t)0x11C, /**< Analog channel 12 status */ /* refer to product datasheet for channel 12 availability */ ADC1_IT_EOC = (uint16_t)0x080 /**< EOC pending bit */ } ADC1_IT_TypeDef; /** * @brief ADC1 Flags */ typedef enum { ADC1_FLAG_OVR = (uint8_t)0x41, /**< Overrun status flag */ ADC1_FLAG_AWD = (uint8_t)0x40, /**< Analog WDG status */ ADC1_FLAG_AWS0 = (uint8_t)0x10, /**< Analog channel 0 status */ ADC1_FLAG_AWS1 = (uint8_t)0x11, /**< Analog channel 1 status */ ADC1_FLAG_AWS2 = (uint8_t)0x12, /**< Analog channel 2 status */ ADC1_FLAG_AWS3 = (uint8_t)0x13, /**< Analog channel 3 status */ ADC1_FLAG_AWS4 = (uint8_t)0x14, /**< Analog channel 4 status */ ADC1_FLAG_AWS5 = (uint8_t)0x15, /**< Analog channel 5 status */ ADC1_FLAG_AWS6 = (uint8_t)0x16, /**< Analog channel 6 status */ ADC1_FLAG_AWS7 = (uint8_t)0x17, /**< Analog channel 7 status */ ADC1_FLAG_AWS8 = (uint8_t)0x18, /**< Analog channel 8 status*/ ADC1_FLAG_AWS9 = (uint8_t)0x19, /**< Analog channel 9 status */ ADC1_FLAG_AWS12 = (uint8_t)0x1C, /**< Analog channel 12 status */ /* refer to product datasheet for channel 12 availability */ ADC1_FLAG_EOC = (uint8_t)0x80 /**< EOC falg */ }ADC1_Flag_TypeDef; /** * @brief ADC1 schmitt Trigger */ typedef enum { ADC1_SCHMITTTRIG_CHANNEL0 = (uint8_t)0x00, /**< Schmitt trigger disable on AIN0 */ ADC1_SCHMITTTRIG_CHANNEL1 = (uint8_t)0x01, /**< Schmitt trigger disable on AIN1 */ ADC1_SCHMITTTRIG_CHANNEL2 = (uint8_t)0x02, /**< Schmitt trigger disable on AIN2 */ ADC1_SCHMITTTRIG_CHANNEL3 = (uint8_t)0x03, /**< Schmitt trigger disable on AIN3 */ ADC1_SCHMITTTRIG_CHANNEL4 = (uint8_t)0x04, /**< Schmitt trigger disable on AIN4 */ ADC1_SCHMITTTRIG_CHANNEL5 = (uint8_t)0x05, /**< Schmitt trigger disable on AIN5 */ ADC1_SCHMITTTRIG_CHANNEL6 = (uint8_t)0x06, /**< Schmitt trigger disable on AIN6 */ ADC1_SCHMITTTRIG_CHANNEL7 = (uint8_t)0x07, /**< Schmitt trigger disable on AIN7 */ ADC1_SCHMITTTRIG_CHANNEL8 = (uint8_t)0x08, /**< Schmitt trigger disable on AIN8 */ ADC1_SCHMITTTRIG_CHANNEL9 = (uint8_t)0x09, /**< Schmitt trigger disable on AIN9 */ ADC1_SCHMITTTRIG_CHANNEL12 = (uint8_t)0x0C, /**< Schmitt trigger disable on AIN12 */ /* refer to product datasheet for channel 12 availability */ ADC1_SCHMITTTRIG_ALL = (uint8_t)0xFF /**< Schmitt trigger disable on All channels */ } ADC1_SchmittTrigg_TypeDef; /** * @brief ADC1 conversion mode selection */ typedef enum { ADC1_CONVERSIONMODE_SINGLE = (uint8_t)0x00, /**< Single conversion mode */ ADC1_CONVERSIONMODE_CONTINUOUS = (uint8_t)0x01 /**< Continuous conversion mode */ } ADC1_ConvMode_TypeDef; /** * @brief ADC1 analog channel selection */ typedef enum { ADC1_CHANNEL_0 = (uint8_t)0x00, /**< Analog channel 0 */ ADC1_CHANNEL_1 = (uint8_t)0x01, /**< Analog channel 1 */ ADC1_CHANNEL_2 = (uint8_t)0x02, /**< Analog channel 2 */ ADC1_CHANNEL_3 = (uint8_t)0x03, /**< Analog channel 3 */ ADC1_CHANNEL_4 = (uint8_t)0x04, /**< Analog channel 4 */ ADC1_CHANNEL_5 = (uint8_t)0x05, /**< Analog channel 5 */ ADC1_CHANNEL_6 = (uint8_t)0x06, /**< Analog channel 6 */ ADC1_CHANNEL_7 = (uint8_t)0x07, /**< Analog channel 7 */ ADC1_CHANNEL_8 = (uint8_t)0x08, /**< Analog channel 8 */ ADC1_CHANNEL_9 = (uint8_t)0x09, /**< Analog channel 9 */ ADC1_CHANNEL_12 = (uint8_t)0x0C /**< Analog channel 12 */ /* refer to product datasheet for channel 12 availability */ } ADC1_Channel_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup ADC1_Private_Macros * @brief Macros used by the assert function to check the different functions parameters. * @{ */ /** * @brief Macro used by the assert function to check the different prescaler's values. */ #define IS_ADC1_PRESSEL_OK(PRESCALER) (((PRESCALER) == ADC1_PRESSEL_FCPU_D2) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D3) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D4) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D6) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D8) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D10) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D12) || \ ((PRESCALER) == ADC1_PRESSEL_FCPU_D18)) /** * @brief Macro used by the assert function to check the different external trigger values. */ #define IS_ADC1_EXTTRIG_OK(EXTRIG) (((EXTRIG) == ADC1_EXTTRIG_TIM) || \ ((EXTRIG) == ADC1_EXTTRIG_GPIO)) /** * @brief Macro used by the assert function to check the different alignment modes. */ #define IS_ADC1_ALIGN_OK(ALIGN) (((ALIGN) == ADC1_ALIGN_LEFT) || \ ((ALIGN) == ADC1_ALIGN_RIGHT)) /** * @brief Macro used by the assert function to check the Interrupt source. */ #define IS_ADC1_IT_OK(IT) (((IT) == ADC1_IT_EOCIE) || \ ((IT) == ADC1_IT_AWDIE)) /** * @brief Macro used by the assert function to check the ADC1 Flag. */ #define IS_ADC1_FLAG_OK(FLAG) (((FLAG) == ADC1_FLAG_EOC)|| \ ((FLAG) == ADC1_FLAG_OVR) || \ ((FLAG) == ADC1_FLAG_AWD) || \ ((FLAG) == ADC1_FLAG_AWS0) || \ ((FLAG) == ADC1_FLAG_AWS1) || \ ((FLAG) == ADC1_FLAG_AWS2) || \ ((FLAG) == ADC1_FLAG_AWS3) || \ ((FLAG) == ADC1_FLAG_AWS4) || \ ((FLAG) == ADC1_FLAG_AWS5) || \ ((FLAG) == ADC1_FLAG_AWS6) || \ ((FLAG) == ADC1_FLAG_AWS7) || \ ((FLAG) == ADC1_FLAG_AWS8) || \ ((FLAG) == ADC1_FLAG_AWS9)) /** * @brief Macro used by the assert function to check the ADC1 pending bits. */ #define IS_ADC1_ITPENDINGBIT_OK(ITPENDINGBIT) (((ITPENDINGBIT) == ADC1_IT_EOC) || \ ((ITPENDINGBIT) == ADC1_IT_AWD) || \ ((ITPENDINGBIT) == ADC1_IT_AWS0) || \ ((ITPENDINGBIT) == ADC1_IT_AWS1) || \ ((ITPENDINGBIT) == ADC1_IT_AWS2) || \ ((ITPENDINGBIT) == ADC1_IT_AWS3) || \ ((ITPENDINGBIT) == ADC1_IT_AWS4) || \ ((ITPENDINGBIT) == ADC1_IT_AWS5) || \ ((ITPENDINGBIT) == ADC1_IT_AWS6) || \ ((ITPENDINGBIT) == ADC1_IT_AWS7) || \ ((ITPENDINGBIT) == ADC1_IT_AWS8) || \ ((ITPENDINGBIT) == ADC1_IT_AWS12) || \ ((ITPENDINGBIT) == ADC1_IT_AWS9)) /** * @brief Macro used by the assert function to check the different schmitt trigger values. */ #define IS_ADC1_SCHMITTTRIG_OK(SCHMITTTRIG) (((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL0) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL1) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL2) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL3) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL4) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL5) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL6) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL7) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL8) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL12) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_ALL) || \ ((SCHMITTTRIG) == ADC1_SCHMITTTRIG_CHANNEL9)) /** * @brief Macro used by the assert function to check the different conversion modes. */ #define IS_ADC1_CONVERSIONMODE_OK(MODE) (((MODE) == ADC1_CONVERSIONMODE_SINGLE) || \ ((MODE) == ADC1_CONVERSIONMODE_CONTINUOUS)) /** * @brief Macro used by the assert function to check the different channels values. */ #define IS_ADC1_CHANNEL_OK(CHANNEL) (((CHANNEL) == ADC1_CHANNEL_0) || \ ((CHANNEL) == ADC1_CHANNEL_1) || \ ((CHANNEL) == ADC1_CHANNEL_2) || \ ((CHANNEL) == ADC1_CHANNEL_3) || \ ((CHANNEL) == ADC1_CHANNEL_4) || \ ((CHANNEL) == ADC1_CHANNEL_5) || \ ((CHANNEL) == ADC1_CHANNEL_6) || \ ((CHANNEL) == ADC1_CHANNEL_7) || \ ((CHANNEL) == ADC1_CHANNEL_8) || \ ((CHANNEL) == ADC1_CHANNEL_12) || \ ((CHANNEL) == ADC1_CHANNEL_9)) /** * @brief Macro used by the assert function to check the possible buffer values. */ #define IS_ADC1_BUFFER_OK(BUFFER) ((BUFFER) <= (uint8_t)0x09) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup ADC1_Exported_Functions * @{ */ void ADC1_DeInit(void); void ADC1_Init(ADC1_ConvMode_TypeDef ADC1_ConversionMode, ADC1_Channel_TypeDef ADC1_Channel, ADC1_PresSel_TypeDef ADC1_PrescalerSelection, ADC1_ExtTrig_TypeDef ADC1_ExtTrigger, FunctionalState ADC1_ExtTriggerState, ADC1_Align_TypeDef ADC1_Align, ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel, FunctionalState ADC1_SchmittTriggerState); void ADC1_Cmd(FunctionalState NewState); void ADC1_ScanModeCmd(FunctionalState NewState); void ADC1_DataBufferCmd(FunctionalState NewState); void ADC1_ITConfig(ADC1_IT_TypeDef ADC1_IT, FunctionalState NewState); void ADC1_PrescalerConfig(ADC1_PresSel_TypeDef ADC1_Prescaler); void ADC1_SchmittTriggerConfig(ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel, FunctionalState NewState); void ADC1_ConversionConfig(ADC1_ConvMode_TypeDef ADC1_ConversionMode, ADC1_Channel_TypeDef ADC1_Channel, ADC1_Align_TypeDef ADC1_Align); void ADC1_ExternalTriggerConfig(ADC1_ExtTrig_TypeDef ADC1_ExtTrigger, FunctionalState NewState); void ADC1_AWDChannelConfig(ADC1_Channel_TypeDef Channel, FunctionalState NewState); void ADC1_StartConversion(void); uint16_t ADC1_GetConversionValue(void); void ADC1_SetHighThreshold(uint16_t Threshold); void ADC1_SetLowThreshold(uint16_t Threshold); uint16_t ADC1_GetBufferValue(uint8_t Buffer); FlagStatus ADC1_GetAWDChannelStatus(ADC1_Channel_TypeDef Channel); FlagStatus ADC1_GetFlagStatus(ADC1_Flag_TypeDef Flag); void ADC1_ClearFlag(ADC1_Flag_TypeDef Flag); ITStatus ADC1_GetITStatus(ADC1_IT_TypeDef ITPendingBit); void ADC1_ClearITPendingBit(ADC1_IT_TypeDef ITPendingBit); /** * @} */ #endif /* __STM8S_ADC1_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_adc2.h ================================================ /** ****************************************************************************** * @file stm8s_adc2.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all the prototypes/macros for the ADC2 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_ADC2_H #define __STM8S_ADC2_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup ADC2_Exported_Types * @{ */ /** * @brief ADC2 clock prescaler selection */ typedef enum { ADC2_PRESSEL_FCPU_D2 = (uint8_t)0x00, /**< Prescaler selection fADC2 = fcpu/2 */ ADC2_PRESSEL_FCPU_D3 = (uint8_t)0x10, /**< Prescaler selection fADC2 = fcpu/3 */ ADC2_PRESSEL_FCPU_D4 = (uint8_t)0x20, /**< Prescaler selection fADC2 = fcpu/4 */ ADC2_PRESSEL_FCPU_D6 = (uint8_t)0x30, /**< Prescaler selection fADC2 = fcpu/6 */ ADC2_PRESSEL_FCPU_D8 = (uint8_t)0x40, /**< Prescaler selection fADC2 = fcpu/8 */ ADC2_PRESSEL_FCPU_D10 = (uint8_t)0x50, /**< Prescaler selection fADC2 = fcpu/10 */ ADC2_PRESSEL_FCPU_D12 = (uint8_t)0x60, /**< Prescaler selection fADC2 = fcpu/12 */ ADC2_PRESSEL_FCPU_D18 = (uint8_t)0x70 /**< Prescaler selection fADC2 = fcpu/18 */ } ADC2_PresSel_TypeDef; /** * @brief ADC2 External conversion trigger event selection */ typedef enum { ADC2_EXTTRIG_TIM = (uint8_t)0x00, /**< Conversion from Internal TIM TRGO event */ ADC2_EXTTRIG_GPIO = (uint8_t)0x01 /**< Conversion from External interrupt on ADC_ETR pin*/ } ADC2_ExtTrig_TypeDef; /** * @brief ADC2 data alignment */ typedef enum { ADC2_ALIGN_LEFT = (uint8_t)0x00, /**< Data alignment left */ ADC2_ALIGN_RIGHT = (uint8_t)0x08 /**< Data alignment right */ } ADC2_Align_TypeDef; /** * @brief ADC2 schmitt Trigger */ typedef enum { ADC2_SCHMITTTRIG_CHANNEL0 = (uint8_t)0x00, /**< Schmitt trigger disable on AIN0 */ ADC2_SCHMITTTRIG_CHANNEL1 = (uint8_t)0x01, /**< Schmitt trigger disable on AIN1 */ ADC2_SCHMITTTRIG_CHANNEL2 = (uint8_t)0x02, /**< Schmitt trigger disable on AIN2 */ ADC2_SCHMITTTRIG_CHANNEL3 = (uint8_t)0x03, /**< Schmitt trigger disable on AIN3 */ ADC2_SCHMITTTRIG_CHANNEL4 = (uint8_t)0x04, /**< Schmitt trigger disable on AIN4 */ ADC2_SCHMITTTRIG_CHANNEL5 = (uint8_t)0x05, /**< Schmitt trigger disable on AIN5 */ ADC2_SCHMITTTRIG_CHANNEL6 = (uint8_t)0x06, /**< Schmitt trigger disable on AIN6 */ ADC2_SCHMITTTRIG_CHANNEL7 = (uint8_t)0x07, /**< Schmitt trigger disable on AIN7 */ ADC2_SCHMITTTRIG_CHANNEL8 = (uint8_t)0x08, /**< Schmitt trigger disable on AIN8 */ ADC2_SCHMITTTRIG_CHANNEL9 = (uint8_t)0x09, /**< Schmitt trigger disable on AIN9 */ ADC2_SCHMITTTRIG_CHANNEL10 = (uint8_t)0x0A, /**< Schmitt trigger disable on AIN10 */ ADC2_SCHMITTTRIG_CHANNEL11 = (uint8_t)0x0B, /**< Schmitt trigger disable on AIN11 */ ADC2_SCHMITTTRIG_CHANNEL12 = (uint8_t)0x0C, /**< Schmitt trigger disable on AIN12 */ ADC2_SCHMITTTRIG_CHANNEL13 = (uint8_t)0x0D, /**< Schmitt trigger disable on AIN13 */ ADC2_SCHMITTTRIG_CHANNEL14 = (uint8_t)0x0E, /**< Schmitt trigger disable on AIN14 */ ADC2_SCHMITTTRIG_CHANNEL15 = (uint8_t)0x0F, /**< Schmitt trigger disable on AIN15 */ ADC2_SCHMITTTRIG_ALL = (uint8_t)0x1F /**< Schmitt trigger disable on all channels */ } ADC2_SchmittTrigg_TypeDef; /** * @brief ADC2 conversion mode selection */ typedef enum { ADC2_CONVERSIONMODE_SINGLE = (uint8_t)0x00, /**< Single conversion mode */ ADC2_CONVERSIONMODE_CONTINUOUS = (uint8_t)0x01 /**< Continuous conversion mode */ } ADC2_ConvMode_TypeDef; /** * @brief ADC2 analog channel selection */ typedef enum { ADC2_CHANNEL_0 = (uint8_t)0x00, /**< Analog channel 0 */ ADC2_CHANNEL_1 = (uint8_t)0x01, /**< Analog channel 1 */ ADC2_CHANNEL_2 = (uint8_t)0x02, /**< Analog channel 2 */ ADC2_CHANNEL_3 = (uint8_t)0x03, /**< Analog channel 3 */ ADC2_CHANNEL_4 = (uint8_t)0x04, /**< Analog channel 4 */ ADC2_CHANNEL_5 = (uint8_t)0x05, /**< Analog channel 5 */ ADC2_CHANNEL_6 = (uint8_t)0x06, /**< Analog channel 6 */ ADC2_CHANNEL_7 = (uint8_t)0x07, /**< Analog channel 7 */ ADC2_CHANNEL_8 = (uint8_t)0x08, /**< Analog channel 8 */ ADC2_CHANNEL_9 = (uint8_t)0x09, /**< Analog channel 9 */ ADC2_CHANNEL_10 = (uint8_t)0x0A, /**< Analog channel 10 */ ADC2_CHANNEL_11 = (uint8_t)0x0B, /**< Analog channel 11 */ ADC2_CHANNEL_12 = (uint8_t)0x0C, /**< Analog channel 12 */ ADC2_CHANNEL_13 = (uint8_t)0x0D, /**< Analog channel 13 */ ADC2_CHANNEL_14 = (uint8_t)0x0E, /**< Analog channel 14 */ ADC2_CHANNEL_15 = (uint8_t)0x0F /**< Analog channel 15 */ } ADC2_Channel_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup ADC2_Private_Macros * @brief Macros used by the assert function to check the different functions parameters. * @{ */ /** * @brief Macro used by the assert function to check the different prescaler's values. */ #define IS_ADC2_PRESSEL_OK(PRESCALER) (((PRESCALER) == ADC2_PRESSEL_FCPU_D2) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D3) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D4) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D6) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D8) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D10) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D12) || \ ((PRESCALER) == ADC2_PRESSEL_FCPU_D18)) /** * @brief Macro used by the assert function to check the different external trigger values. */ #define IS_ADC2_EXTTRIG_OK(EXTRIG) (((EXTRIG) == ADC2_EXTTRIG_TIM) || \ ((EXTRIG) == ADC2_EXTTRIG_GPIO)) /** * @brief Macro used by the assert function to check the different alignment modes. */ #define IS_ADC2_ALIGN_OK(ALIGN) (((ALIGN) == ADC2_ALIGN_LEFT) || \ ((ALIGN) == ADC2_ALIGN_RIGHT)) /** * @brief Macro used by the assert function to check the different schmitt trigger values. */ #define IS_ADC2_SCHMITTTRIG_OK(SCHMITTTRIG) (((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL0) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL1) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL2) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL3) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL4) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL5) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL6) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL7) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL8) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL9) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL10) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL11) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL12) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL13) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL14) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_CHANNEL15) || \ ((SCHMITTTRIG) == ADC2_SCHMITTTRIG_ALL)) /** * @brief Macro used by the assert function to check the different conversion modes. */ #define IS_ADC2_CONVERSIONMODE_OK(MODE) (((MODE) == ADC2_CONVERSIONMODE_SINGLE) || \ ((MODE) == ADC2_CONVERSIONMODE_CONTINUOUS)) /** * @brief Macro used by the assert function to check the different channels values. */ #define IS_ADC2_CHANNEL_OK(CHANNEL) (((CHANNEL) == ADC2_CHANNEL_0) || \ ((CHANNEL) == ADC2_CHANNEL_1) || \ ((CHANNEL) == ADC2_CHANNEL_2) || \ ((CHANNEL) == ADC2_CHANNEL_3) || \ ((CHANNEL) == ADC2_CHANNEL_4) || \ ((CHANNEL) == ADC2_CHANNEL_5) || \ ((CHANNEL) == ADC2_CHANNEL_6) || \ ((CHANNEL) == ADC2_CHANNEL_7) || \ ((CHANNEL) == ADC2_CHANNEL_8) || \ ((CHANNEL) == ADC2_CHANNEL_9) || \ ((CHANNEL) == ADC2_CHANNEL_10) || \ ((CHANNEL) == ADC2_CHANNEL_11) || \ ((CHANNEL) == ADC2_CHANNEL_12) || \ ((CHANNEL) == ADC2_CHANNEL_13) || \ ((CHANNEL) == ADC2_CHANNEL_14) || \ ((CHANNEL) == ADC2_CHANNEL_15)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup ADC2_Exported_Functions * @{ */ void ADC2_DeInit(void); void ADC2_Init(ADC2_ConvMode_TypeDef ADC2_ConversionMode, ADC2_Channel_TypeDef ADC2_Channel, ADC2_PresSel_TypeDef ADC2_PrescalerSelection, ADC2_ExtTrig_TypeDef ADC2_ExtTrigger, FunctionalState ADC2_ExtTriggerState, ADC2_Align_TypeDef ADC2_Align, ADC2_SchmittTrigg_TypeDef ADC2_SchmittTriggerChannel, FunctionalState ADC2_SchmittTriggerState); void ADC2_Cmd(FunctionalState NewState); void ADC2_ITConfig(FunctionalState NewState); void ADC2_PrescalerConfig(ADC2_PresSel_TypeDef ADC2_Prescaler); void ADC2_SchmittTriggerConfig(ADC2_SchmittTrigg_TypeDef ADC2_SchmittTriggerChannel, FunctionalState NewState); void ADC2_ConversionConfig(ADC2_ConvMode_TypeDef ADC2_ConversionMode, ADC2_Channel_TypeDef ADC2_Channel, ADC2_Align_TypeDef ADC2_Align); void ADC2_ExternalTriggerConfig(ADC2_ExtTrig_TypeDef ADC2_ExtTrigger, FunctionalState NewState); void ADC2_StartConversion(void); uint16_t ADC2_GetConversionValue(void); FlagStatus ADC2_GetFlagStatus(void); void ADC2_ClearFlag(void); ITStatus ADC2_GetITStatus(void); void ADC2_ClearITPendingBit(void); /** * @} */ #endif /* __STM8S_ADC2_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_awu.h ================================================ /** ****************************************************************************** * @file stm8s_awu.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the AWU peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_AWU_H #define __STM8S_AWU_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup AWU_Exported_Types * @{ */ /** * @brief AWU TimeBase selection */ typedef enum { AWU_TIMEBASE_NO_IT = (uint8_t)0, /*!< No AWU interrupt selected */ AWU_TIMEBASE_250US = (uint8_t)1, /*!< AWU Timebase equals 0.25 ms */ AWU_TIMEBASE_500US = (uint8_t)2, /*!< AWU Timebase equals 0.5 ms */ AWU_TIMEBASE_1MS = (uint8_t)3, /*!< AWU Timebase equals 1 ms */ AWU_TIMEBASE_2MS = (uint8_t)4, /*!< AWU Timebase equals 2 ms */ AWU_TIMEBASE_4MS = (uint8_t)5, /*!< AWU Timebase equals 4 ms */ AWU_TIMEBASE_8MS = (uint8_t)6, /*!< AWU Timebase equals 8 ms */ AWU_TIMEBASE_16MS = (uint8_t)7, /*!< AWU Timebase equals 16 ms */ AWU_TIMEBASE_32MS = (uint8_t)8, /*!< AWU Timebase equals 32 ms */ AWU_TIMEBASE_64MS = (uint8_t)9, /*!< AWU Timebase equals 64 ms */ AWU_TIMEBASE_128MS = (uint8_t)10, /*!< AWU Timebase equals 128 ms */ AWU_TIMEBASE_256MS = (uint8_t)11, /*!< AWU Timebase equals 256 ms */ AWU_TIMEBASE_512MS = (uint8_t)12, /*!< AWU Timebase equals 512 ms */ AWU_TIMEBASE_1S = (uint8_t)13, /*!< AWU Timebase equals 1 s */ AWU_TIMEBASE_2S = (uint8_t)14, /*!< AWU Timebase equals 2 s */ AWU_TIMEBASE_12S = (uint8_t)15, /*!< AWU Timebase equals 12 s */ AWU_TIMEBASE_30S = (uint8_t)16 /*!< AWU Timebase equals 30 s */ } AWU_Timebase_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /** @addtogroup AWU_Exported_Constants * @{ */ #define LSI_FREQUENCY_MIN ((uint32_t)110000) /*!< LSI minimum value in Hertz */ #define LSI_FREQUENCY_MAX ((uint32_t)150000) /*!< LSI maximum value in Hertz */ /** * @} */ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup AWU_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert function to check the AWU timebases */ #define IS_AWU_TIMEBASE_OK(TB) \ (((TB) == AWU_TIMEBASE_NO_IT) || \ ((TB) == AWU_TIMEBASE_250US) || \ ((TB) == AWU_TIMEBASE_500US) || \ ((TB) == AWU_TIMEBASE_1MS) || \ ((TB) == AWU_TIMEBASE_2MS) || \ ((TB) == AWU_TIMEBASE_4MS) || \ ((TB) == AWU_TIMEBASE_8MS) || \ ((TB) == AWU_TIMEBASE_16MS) || \ ((TB) == AWU_TIMEBASE_32MS) || \ ((TB) == AWU_TIMEBASE_64MS) || \ ((TB) == AWU_TIMEBASE_128MS) || \ ((TB) == AWU_TIMEBASE_256MS) || \ ((TB) == AWU_TIMEBASE_512MS) || \ ((TB) == AWU_TIMEBASE_1S) || \ ((TB) == AWU_TIMEBASE_2S) || \ ((TB) == AWU_TIMEBASE_12S) || \ ((TB) == AWU_TIMEBASE_30S)) /** * @brief Macro used by the assert function to check the LSI frequency (in Hz) */ #define IS_LSI_FREQUENCY_OK(FREQ) \ (((FREQ) >= LSI_FREQUENCY_MIN) && \ ((FREQ) <= LSI_FREQUENCY_MAX)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup AWU_Exported_Functions * @{ */ void AWU_DeInit(void); void AWU_Init(AWU_Timebase_TypeDef AWU_TimeBase); void AWU_Cmd(FunctionalState NewState); void AWU_LSICalibrationConfig(uint32_t LSIFreqHz); void AWU_IdleModeEnable(void); FlagStatus AWU_GetFlagStatus(void); /** * @} */ #endif /* __STM8S_AWU_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_beep.h ================================================ /** ****************************************************************************** * @file stm8s_beep.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the BEEP peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_BEEP_H #define __STM8S_BEEP_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup BEEP_Exported_Types * @{ */ /** * @brief BEEP Frequency selection */ typedef enum { BEEP_FREQUENCY_1KHZ = (uint8_t)0x00, /*!< Beep signal output frequency equals to 1 KHz */ BEEP_FREQUENCY_2KHZ = (uint8_t)0x40, /*!< Beep signal output frequency equals to 2 KHz */ BEEP_FREQUENCY_4KHZ = (uint8_t)0x80 /*!< Beep signal output frequency equals to 4 KHz */ } BEEP_Frequency_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /** @addtogroup BEEP_Exported_Constants * @{ */ #define BEEP_CALIBRATION_DEFAULT ((uint8_t)0x0B) /*!< Default value when calibration is not done */ #define LSI_FREQUENCY_MIN ((uint32_t)110000) /*!< LSI minimum value in Hertz */ #define LSI_FREQUENCY_MAX ((uint32_t)150000) /*!< LSI maximum value in Hertz */ /** * @} */ /* Exported macros -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup BEEP_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert function to check the BEEP frequencies. */ #define IS_BEEP_FREQUENCY_OK(FREQ) \ (((FREQ) == BEEP_FREQUENCY_1KHZ) || \ ((FREQ) == BEEP_FREQUENCY_2KHZ) || \ ((FREQ) == BEEP_FREQUENCY_4KHZ)) /** * @brief Macro used by the assert function to check the LSI frequency (in Hz). */ #define IS_LSI_FREQUENCY_OK(FREQ) \ (((FREQ) >= LSI_FREQUENCY_MIN) && \ ((FREQ) <= LSI_FREQUENCY_MAX)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup BEEP_Exported_Functions * @{ */ void BEEP_DeInit(void); void BEEP_Init(BEEP_Frequency_TypeDef BEEP_Frequency); void BEEP_Cmd(FunctionalState NewState); void BEEP_LSICalibrationConfig(uint32_t LSIFreqHz); /** * @} */ #endif /* __STM8S_BEEP_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_can.h ================================================ /** ****************************************************************************** * @file stm8s_can.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all the functions for the CAN peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_CAN_H #define __STM8S_CAN_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported constants --------------------------------------------------------*/ #define CAN_STDID_SIZE ((uint16_t)0x07FF) #define CAN_EXTID_SIZE ((uint32_t)0x1FFFFFFF) #define CAN_DLC_MAX ((uint8_t)0x08) /** @addtogroup CAN_Exported_Types * @{ */ /** * @brief CAN Page Mapping */ typedef enum { CAN_Page_TxMailBox0 = ((uint8_t) 0), /*!< CAN TX mailbox 0 reg page */ CAN_Page_TxMailBox1 = ((uint8_t) 1), /*!< CAN TX mailbox 1 reg page */ CAN_Page_TxMailBox2 = ((uint8_t) 5), /*!< CAN TX mailbox 2 reg page */ CAN_Page_Filter01 = ((uint8_t) 2), /*!< CAN Filters 0 & 1 reg page*/ CAN_Page_Filter23 = ((uint8_t) 3), /*!< CAN Filters 2 & 3 reg page*/ CAN_Page_Filter45 = ((uint8_t) 4), /*!< CAN Filters 4 & 5 reg page*/ CAN_Page_Config = ((uint8_t) 6), /*!< CAN Configuration control/status reg page*/ CAN_Page_RxFifo = ((uint8_t) 7) /*!< CAN RX FIFO registers page */ }CAN_Page_TypeDef; /** * @brief CAN sleep constants */ typedef enum { CAN_InitStatus_Failed =0, /*!< CAN initialization failed */ CAN_InitStatus_Success =! CAN_InitStatus_Failed /*!< CAN initialization OK*/ } CAN_InitStatus_TypeDef; /** * @brief CAN operating mode */ typedef enum { CAN_OperatingMode_Initialization =((uint8_t)0x00), /*!< Initialization mode */ CAN_OperatingMode_Normal =((uint8_t)0x01), /*!< Normal mode */ CAN_OperatingMode_Sleep =((uint8_t)0x02) /*!< sleep mode */ }CAN_OperatingMode_TypeDef; /** * @brief CAN operating mode status */ typedef enum { CAN_ModeStatus_Failed = ((uint8_t)0x00), /*!< CAN entering the specific mode failed */ CAN_ModeStatus_Success =! CAN_ModeStatus_Failed /*!< CAN entering the specific mode Succeed */ }CAN_ModeStatus_TypeDef; /** * @brief CAN Time Triggered Communication mode */ typedef enum { CAN_MasterCtrl_AllDisabled =((uint8_t)0x00), /*!< CAN ALL Master Control Option are DISABLED */ CAN_MasterCtrl_AllEnabled =((uint8_t)0xFC), /*!< CAN ALL Master Control Option are DISABLED */ CAN_MasterCtrl_TimeTriggerCOMMode =((uint8_t)0x80), /*!< CAN Time Triggered Communication mode ENABLED */ CAN_MasterCtrl_AutoBusOffManagement =((uint8_t)0x40), /*!< CAN Auto Bus Off Management ENABLED */ CAN_MasterCtrl_AutoWakeUpMode =((uint8_t)0x20), /*!< CAN Automatic WakeUp Mode ENABLED , sleep mode is left automatically by hardware */ CAN_MasterCtrl_NoAutoReTx =((uint8_t)0x10), /*!< CAN Non Automatic Retransmission ENABLED, MSG will be transmitted only once */ CAN_MasterCtrl_RxFifoLockedMode =((uint8_t)0x08), /*!< CAN Receive FIFO Locked against overrun ENABLED */ CAN_MasterCtrl_TxFifoPriority =((uint8_t)0x04) /*!< CAN Transmit FIFO Priority driven by the request order (not by the identifier of the MSG) */ }CAN_MasterCtrl_TypeDef; /** * @brief CAN mode options */ typedef enum { CAN_Mode_Normal =((uint8_t)0x00), /*!< normal mode */ CAN_Mode_LoopBack =((uint8_t)0x01), /*!< loopback mode */ CAN_Mode_Silent =((uint8_t)0x02), /*!< silent mode */ CAN_Mode_Silent_LoopBack =((uint8_t)0x03) /*!< loopback combined with silent mode */ }CAN_Mode_TypeDef; /** * @brief CAN synchronisation jump width (SJW)*/ typedef enum { CAN_SynJumpWidth_1TimeQuantum =((uint8_t)0x00), /*!< 1 time quantum */ CAN_SynJumpWidth_2TimeQuantum =((uint8_t)0x40), /*!< 2 time quantum */ CAN_SynJumpWidth_3TimeQuantum =((uint8_t)0x80), /*!< 3 time quantum */ CAN_SynJumpWidth_4TimeQuantum =((uint8_t)0xC0) /*!< 4 time quantum */ }CAN_SynJumpWidth_TypeDef; /** * @brief time quantum in bit segment 1 */ typedef enum { CAN_BitSeg1_1TimeQuantum =((uint8_t)0x00), /*!< 1 time quantum */ CAN_BitSeg1_2TimeQuantum =((uint8_t)0x01), /*!< 2 time quantum */ CAN_BitSeg1_3TimeQuantum =((uint8_t)0x02), /*!< 3 time quantum */ CAN_BitSeg1_4TimeQuantum =((uint8_t)0x03) , /*!< 4 time quantum */ CAN_BitSeg1_5TimeQuantum =((uint8_t)0x04) , /*!< 5 time quantum */ CAN_BitSeg1_6TimeQuantum =((uint8_t)0x05) , /*!< 6 time quantum */ CAN_BitSeg1_7TimeQuantum =((uint8_t)0x06) , /*!< 7 time quantum */ CAN_BitSeg1_8TimeQuantum =((uint8_t)0x07), /*!< 8 time quantum */ CAN_BitSeg1_9TimeQuantum =((uint8_t)0x08), /*!< 9 time quantum */ CAN_BitSeg1_10TimeQuantum =((uint8_t)0x09), /*!< 10 time quantum */ CAN_BitSeg1_11TimeQuantum =((uint8_t)0x0A), /*!< 11 time quantum */ CAN_BitSeg1_12TimeQuantum =((uint8_t)0x0B), /*!< 12 time quantum */ CAN_BitSeg1_13TimeQuantum =((uint8_t)0x0C), /*!< 13 time quantum */ CAN_BitSeg1_14TimeQuantum =((uint8_t)0x0D), /*!< 14 time quantum */ CAN_BitSeg1_15TimeQuantum =((uint8_t)0x0E), /*!< 15 time quantum */ CAN_BitSeg1_16TimeQuantum =((uint8_t)0x0F) /*!< 16 time quantum */ }CAN_BitSeg1_TypeDef; /** * @brief time quantum in bit segment 2 */ typedef enum { CAN_BitSeg2_1TimeQuantum = ((uint8_t)0x00), /*!< 1 time quantum */ CAN_BitSeg2_2TimeQuantum = ((uint8_t)0x10), /*!< 2 time quantum */ CAN_BitSeg2_3TimeQuantum = ((uint8_t)0x20), /*!< 3 time quantum */ CAN_BitSeg2_4TimeQuantum = ((uint8_t)0x30), /*!< 4 time quantum */ CAN_BitSeg2_5TimeQuantum = ((uint8_t)0x40), /*!< 5 time quantum */ CAN_BitSeg2_6TimeQuantum = ((uint8_t)0x50), /*!< 6 time quantum */ CAN_BitSeg2_7TimeQuantum = ((uint8_t)0x60), /*!< 7 time quantum */ CAN_BitSeg2_8TimeQuantum = ((uint8_t)0x70) /*!< 8 time quantum */ }CAN_BitSeg2_TypeDef; /** * @brief CAN filter number */ typedef enum { CAN_FilterNumber_0 = ((uint8_t)0x00), /*!< Filter number 0 */ CAN_FilterNumber_1 = ((uint8_t)0x01), /*!< Filter number 1 */ CAN_FilterNumber_2 = ((uint8_t)0x02), /*!< Filter number 2 */ CAN_FilterNumber_3 = ((uint8_t)0x03), /*!< Filter number 3 */ CAN_FilterNumber_4 = ((uint8_t)0x04), /*!< Filter number 4 */ CAN_FilterNumber_5 = ((uint8_t)0x05) /*!< Filter number 5 */ }CAN_FilterNumber_TypeDef; /** * @brief CAN filter mode */ typedef enum { CAN_FilterMode_IdMask = ((uint8_t)0x00), /*!< id/mask mode */ CAN_FilterMode_IdMask_IdList = ((uint8_t)0x10), /*!< Id/Mask mode First and IdList mode second */ CAN_FilterMode_IdList_IdMask = ((uint8_t)0x11), /*!< IdList mode First and IdMask mode second */ CAN_FilterMode_IdList = ((uint8_t)0x01) /*!< identifier list mode */ }CAN_FilterMode_TypeDef; /** * @brief CAN filter scale */ typedef enum { CAN_FilterScale_8Bit =((uint8_t)0x00), /*!< 8-bit filter scale */ CAN_FilterScale_16_8Bit =((uint8_t)0x02), /*!< 16/8-bit filter scale */ CAN_FilterScale_16Bit =((uint8_t)0x04), /*!< 16-bit filter scale */ CAN_FilterScale_32Bit =((uint8_t)0x06) /*!< 32-bit filter scale */ }CAN_FilterScale_TypeDef; /** * @brief CAN Tx mailboxes*/ typedef enum { CAN_TransmitMailBox_0 = ((uint8_t) 0x00), /*!< CAN TX mailbox 0 reg page */ CAN_TransmitMailBox_1 = ((uint8_t) 0x01), /*!< CAN TX mailbox 1 reg page */ CAN_TransmitMailBox_2 = ((uint8_t) 0x05) /*!< CAN TX mailbox 2 reg page */ }CAN_TransmitMailBox_TypeDef; /** * @brief CAN Pending Messages number*/ typedef enum { CAN_NbrPendingMessage_0 = ((uint8_t)0x00), /*!< No Msg Pending */ CAN_NbrPendingMessage_1 = ((uint8_t)0x01), /*!< 1 Msg Pending */ CAN_NbrPendingMessage_2 = ((uint8_t)0x02), /*!< 2 Msg Pending */ CAN_NbrPendingMessage_3 = ((uint8_t)0x03) /*!< 3 Msg Pending */ }CAN_NbrPendingMessage_TypeDef; /** * @brief CAN identifier type */ typedef enum { CAN_Id_Standard =((uint8_t)0x00), /*!< Standard Id */ CAN_Id_Extended =((uint8_t)0x40) /*!< Extended Id */ }CAN_Id_TypeDef; /** * @brief CAN remote transmission request */ typedef enum { CAN_RTR_Data = ((uint8_t)0x00), /*!< Data frame */ CAN_RTR_Remote = ((uint8_t)0x20) /*!< Remote frame */ }CAN_RTR_TypeDef; /** * @brief CAN transmit Status */ typedef enum { CAN_TxStatus_Failed =((uint8_t)0xF0), /*!< CAN transmission failed */ CAN_TxStatus_Ok =((uint8_t)0xF1), /*!< CAN transmission succeeded */ CAN_TxStatus_Pending =((uint8_t)0xF2), /*!< CAN transmission pending */ CAN_TxStatus_NoMailBox =((uint8_t)0xF4), /*!< CAN cell did not provide an empty mailbox */ CAN_TxStatus_MailBoxEmpty =((uint8_t)0xF5), /*!< CAN Tx mailbox is Empty */ CAN_TxStatus_MailBox0Ok =((uint8_t)0x00), /*!< CAN transmission succeeded by mail box 1*/ CAN_TxStatus_MailBox1Ok =((uint8_t)0x01), /*!< CAN transmission succeeded by mail box 2*/ CAN_TxStatus_MailBox2Ok =((uint8_t)0x05) /*!< CAN transmission succeeded by mail box 3*/ }CAN_TxStatus_TypeDef; /** * @brief CAN sleep Status */ typedef enum { CAN_Sleep_Failed = ((uint8_t)0x00), /*!< CAN did not enter the sleep mode */ CAN_Sleep_Ok = ((uint8_t)0x01) /*!< CAN entered the sleep mode */ }CAN_Sleep_TypeDef; /** * @brief CAN wake up status */ typedef enum { CAN_WakeUp_Failed = ((uint8_t)0x00), /*!< CAN did not leave the sleep mode */ CAN_WakeUp_Ok = ((uint8_t)0x01) /*!< CAN leaved the sleep mode */ }CAN_WakeUp_TypeDef; /** * @brief CAN flags */ typedef enum { /* if the flag is 0x3XXX, it means that it can be got (CAN_GetFlagStatus) and Cleared (CAN_ClearFlag) */ /* if the flag is 0x1XXX, it means that it can only be got (CAN_GetFlagStatus) */ /*Transmit Flags*/ CAN_FLAG_RQCP0 =((uint16_t)0x3401), /*!< Request MailBox0 Flag */ CAN_FLAG_RQCP1 =((uint16_t)0x3402), /*!< Request MailBox1 Flag */ CAN_FLAG_RQCP2 =((uint16_t)0x3404), /*!< Request MailBox2 Flag */ /*Receive Flags*/ CAN_FLAG_FMP =((uint16_t)0x1203), /*!< FIFO Message Pending Flag */ CAN_FLAG_FF =((uint16_t)0x3208), /*!< FIFO Full Flag */ CAN_FLAG_FOV =((uint16_t)0x3210), /*!< FIFO Overrun Flag */ /*Wake up Flag*/ CAN_FLAG_WKU =((uint16_t)0x3108), /*!< wake up Flag */ /*Error Flags*/ CAN_FLAG_EWG =((uint16_t)0x1001), /*!< Error Warning Flag */ CAN_FLAG_EPV =((uint16_t)0x1002), /*!< Error Passive Flag */ CAN_FLAG_BOF =((uint16_t)0x1004), /*!< Bus-Off Flag */ CAN_FLAG_LEC =((uint16_t)0x3070) /*!< Last error code Flag */ }CAN_FLAG_TypeDef; /** * @brief CAN interrupts */ typedef enum { /*Transmit Interruption*/ CAN_IT_TME =((uint16_t)0x0001), /*!< Transmit mailbox empty interrupt */ /*Receive Interruptions*/ CAN_IT_FMP =((uint16_t)0x0002), /*!< FIFO message pending interrupt */ CAN_IT_FF =((uint16_t)0x0004), /*!< FIFO full interrupt */ CAN_IT_FOV =((uint16_t)0x0008), /*!< FIFO overrun interrupt */ /*Wake Up Interruption*/ CAN_IT_WKU =((uint16_t)0x0080), /*!< Wake-up interrupt */ /*Error Interruptions*/ CAN_IT_ERR =((uint16_t)0x4000), /*!< Genaral Error interrupt */ CAN_IT_EWG =((uint16_t)0x0100), /*!< Error warning interrupt */ CAN_IT_EPV =((uint16_t)0x0200), /*!< Error passive interrupt */ CAN_IT_BOF =((uint16_t)0x0400), /*!< Bus-off interrupt */ CAN_IT_LEC =((uint16_t)0x0800) /*!< Last error code interrupt */ } CAN_IT_TypeDef; /** * @brief CAN ST7 Compatibility*/ typedef enum { CAN_ST7Compatibility_Enable = ((uint8_t)0x00), /*!< CAN is compatible with ST7 beCAN (only 2 mailboxes are available)*/ CAN_ST7Compatibility_Disable = ((uint8_t)0x10) /*!< CAN is not compatible with ST7 beCAN ( 3 mailboxes are available)*/ }CAN_ST7Compatibility_TypeDef; /** * @brief CAN Error Code description */ typedef enum { CAN_ErrorCode_NoErr = ((uint8_t)0x00), /*!< No Error */ CAN_ErrorCode_StuffErr = ((uint8_t)0x10), /*!< Stuff Error */ CAN_ErrorCode_FormErr = ((uint8_t)0x20), /*!< Form Error */ CAN_ErrorCode_ACKErr = ((uint8_t)0x30), /*!< Acknowledgment Error */ CAN_ErrorCode_BitRecessiveErr = ((uint8_t)0x40), /*!< Bit Recessive Error */ CAN_ErrorCode_BitDominantErr = ((uint8_t)0x50), /*!< Bit Dominant Error */ CAN_ErrorCode_CRCErr = ((uint8_t)0x60), /*!< CRC Error */ CAN_ErrorCode_SoftwareSetErr = ((uint8_t)0x70) /*!< Software Set Error */ }CAN_ErrorCode_TypeDef; /** * @} */ /* Private macros ------------------------------------------------------------*/ /** @addtogroup CAN_Private_Macros * @{ */ /** * @brief Macro used by the assert function in order to check the CAN ST7 Compatibility parameters. */ #define IS_CAN_ST7_COMPATIBILITY_OK(STATE) (((STATE) == CAN_ST7Compatibility_Enable) || ((STATE) == CAN_ST7Compatibility_Disable)) /** * @brief Macro used by the assert function in order to check CAN operating mode. */ #define IS_CAN_OPERATINGMODE_OK(MODE) (((MODE) == CAN_OperatingMode_Initialization) ||\ ((MODE) == CAN_OperatingMode_Normal)|| \ ((MODE) == CAN_OperatingMode_Sleep)) /** * @brief Macro used by the assert function in order to check CAN Time Triggered Communication mode. */ #define IS_CAN_MASTERCTRL_OK(MODE) (((MODE) == CAN_MasterCtrl_AllDisabled) || \ (((MODE) <= CAN_MasterCtrl_AllEnabled) && ((MODE) >= CAN_MasterCtrl_TxFifoPriority))) /** * @brief Macro used by the assert function in order to check CAN mode options . */ #define IS_CAN_MODE_OK(MODE) (((MODE) == CAN_Mode_Normal) || ((MODE) == CAN_Mode_LoopBack)|| \ ((MODE) == CAN_Mode_Silent) || ((MODE) == CAN_Mode_Silent_LoopBack)) /** * @brief Macro used by the assert function in order to check the CAN synchronisation jump width (SJW). */ #define IS_CAN_SYNJUMPWIDTH_OK(SJW) (((SJW) == CAN_SynJumpWidth_1TimeQuantum) || ((SJW) == CAN_SynJumpWidth_2TimeQuantum)|| \ ((SJW) == CAN_SynJumpWidth_3TimeQuantum) || ((SJW) == CAN_SynJumpWidth_4TimeQuantum)) /** * @brief Macro used by the assert function in order to check time quantum in bit segment 1 . */ #define IS_CAN_BITSEG1_OK(BS1) ((BS1) <= CAN_BitSeg1_16TimeQuantum) /** * @brief Macro used by the assert function in order to check time quantum in bit segment 2. */ #define IS_CAN_BITSEG2_OK(BS2) ((((BS2) >= CAN_BitSeg2_2TimeQuantum) && ((BS2) <= CAN_BitSeg2_8TimeQuantum))|| ((BS2) == CAN_BitSeg2_1TimeQuantum)) /** * @brief Macro used by the assert function in order to check CAN clock prescaler. */ #define IS_CAN_PRESCALER_OK(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 64)) /** * @brief Macro used by the assert function in order to check CAN filter number. */ #define IS_CAN_FILTER_NUMBER_OK(NUMBER) (((NUMBER) == CAN_FilterNumber_0) || \ ((NUMBER) == CAN_FilterNumber_1) || \ ((NUMBER) == CAN_FilterNumber_2) || \ ((NUMBER) == CAN_FilterNumber_3) || \ ((NUMBER) == CAN_FilterNumber_4) || \ ((NUMBER) == CAN_FilterNumber_5)) /** * @brief Macro used by the assert function in order to check CAN filter mode. */ #define IS_CAN_FILTER_MODE_OK(MODE) (((MODE) == CAN_FilterMode_IdMask) || \ ((MODE) == CAN_FilterMode_IdMask_IdList) || \ ((MODE) == CAN_FilterMode_IdList_IdMask) || \ ((MODE) == CAN_FilterMode_IdList)) /** * @brief Macro used by the assert function in order to check CAN filter scale. */ #define IS_CAN_FILTER_SCALE_OK(SCALE) (((SCALE) == CAN_FilterScale_8Bit)|| \ ((SCALE) == CAN_FilterScale_16_8Bit) ||\ ((SCALE) == CAN_FilterScale_16Bit )||\ ((SCALE) == CAN_FilterScale_32Bit)) /** * @brief Macro used by the assert function in order to check CAN Tx mailboxes. */ #define IS_CAN_TRANSMITMAILBOX_OK(TRANSMITMAILBOX) (((TRANSMITMAILBOX) == CAN_TransmitMailBox_0) || \ ((TRANSMITMAILBOX) == CAN_TransmitMailBox_1) || \ ((TRANSMITMAILBOX) == CAN_TransmitMailBox_2)) /** * @brief Macro used by the assert function in order to check the Standard ID to be sent. */ #define IS_CAN_STDID_OK(STDID) ((STDID) <= ((uint16_t)CAN_STDID_SIZE)) /** * @brief Macro used by the assert function in order to check the Extended ID to be sent. */ #define IS_CAN_EXTID_OK(EXTID) ((EXTID) <= ((uint32_t)CAN_EXTID_SIZE)) /** * @brief Macro used by the assert function in order to check the DLC to be sent. */ #define IS_CAN_DLC_OK(DLC) ((DLC) <= CAN_DLC_MAX) /** * @brief Macro used by the assert function in order to check the type of the ID to be sent. */ #define IS_CAN_IDTYPE_OK(IDTYPE) (((IDTYPE) == CAN_Id_Standard) || ((IDTYPE) == CAN_Id_Extended)) /** * @brief Macro used by the assert function in order to check CAN transmission Frame Type. */ #define IS_CAN_RTR_OK(RTR) (((RTR) == CAN_RTR_Data) || ((RTR) == CAN_RTR_Remote)) /** * @brief Macro used by the assert function in order to check CAN flags which can be got by @ref CAN_GetFlagStatus */ #define IS_CAN_FLAG_STATUS_OK(FLAG) (((FLAG) == CAN_FLAG_RQCP0) || ((FLAG) == CAN_FLAG_RQCP1) ||\ ((FLAG) == CAN_FLAG_RQCP2) || ((FLAG) == CAN_FLAG_FMP) ||\ ((FLAG) == CAN_FLAG_FF) || ((FLAG) == CAN_FLAG_FOV) ||\ ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_EWG) ||\ ((FLAG) == CAN_FLAG_EPV) || ((FLAG) == CAN_FLAG_BOF) ||\ ((FLAG) == CAN_FLAG_LEC)) /** * @brief Macro used by the assert function in order to check CAN flags which can be cleared by @ref CAN_ClearFlag */ #define IS_CAN_FLAG_CLEAR_OK(FLAG) (((FLAG) == CAN_FLAG_RQCP0) || ((FLAG) == CAN_FLAG_RQCP1) ||\ ((FLAG) == CAN_FLAG_RQCP2) || ((FLAG) == CAN_FLAG_FF) ||\ ((FLAG) == CAN_FLAG_FOV) || ((FLAG) == CAN_FLAG_WKU) ||\ ((FLAG) == CAN_FLAG_LEC)) /** * @brief Macro used by the assert function in order to check the CAN Configuration interrupts. */ #define CAN_IT_CONFIG_MASK ~(uint16_t)(CAN_IT_TME|CAN_IT_FMP|CAN_IT_FF|CAN_IT_FOV|CAN_IT_WKU|CAN_IT_EWG|CAN_IT_EPV|CAN_IT_BOF|CAN_IT_LEC|CAN_IT_ERR) #define IS_CAN_IT_CONFIG_OK(IT) (((IT) != 0x0000) && ((uint16_t)((uint16_t)(IT) & (uint16_t)CAN_IT_CONFIG_MASK) == 0x0000)) /** * @brief Macro used by the assert function in order to check the CAN status interrupts. */ #define IS_CAN_IT_STATUS_OK(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP) ||\ ((IT) == CAN_IT_FF) || ((IT) == CAN_IT_FOV) || \ ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_ERR) || \ ((IT) == CAN_IT_EWG) || ((IT) == CAN_IT_EPV) || \ ((IT) == CAN_IT_BOF) || ((IT) == CAN_IT_LEC) ) /** * @brief Macro used by the assert function in order to check the CAN Pending bit interrupts. */ #define IS_CAN_IT_PENDING_BIT_OK(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FF) ||\ ((IT) == CAN_IT_FOV) || ((IT) == CAN_IT_WKU) ||\ ((IT) == CAN_IT_ERR) || ((IT) == CAN_IT_EWG) ||\ ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF)||\ ((IT) == CAN_IT_LEC)) /** * @brief Macro used by the assert function in order to check the Last Error Code. */ #define IS_CAN_LAST_ERROR_CODE_OK(CODE) (((CODE) & 0x8F) == 0x00) /** * @} */ /* Exported function prototypes --------------------------------------------- */ /** @addtogroup CAN_Exported_Functions * @{ */ void CAN_DeInit(void); CAN_InitStatus_TypeDef CAN_Init(CAN_MasterCtrl_TypeDef CAN_MasterCtrl, CAN_Mode_TypeDef CAN_Mode, CAN_SynJumpWidth_TypeDef CAN_SynJumpWidth, CAN_BitSeg1_TypeDef CAN_BitSeg1, CAN_BitSeg2_TypeDef CAN_BitSeg2, uint8_t CAN_Prescaler); void CAN_FilterInit(CAN_FilterNumber_TypeDef CAN_FilterNumber, FunctionalState CAN_FilterActivation, CAN_FilterMode_TypeDef CAN_FilterMode, CAN_FilterScale_TypeDef CAN_FilterScale, uint8_t CAN_FilterID1, uint8_t CAN_FilterID2, uint8_t CAN_FilterID3, uint8_t CAN_FilterID4, uint8_t CAN_FilterIDMask1, uint8_t CAN_FilterIDMask2, uint8_t CAN_FilterIDMask3, uint8_t CAN_FilterIDMask4); void CAN_ITConfig(CAN_IT_TypeDef CAN_IT, FunctionalState NewState); void CAN_ST7CompatibilityCmd(CAN_ST7Compatibility_TypeDef CAN_ST7Compatibility); CAN_TxStatus_TypeDef CAN_Transmit( uint32_t CAN_Id, CAN_Id_TypeDef CAN_IDE, CAN_RTR_TypeDef CAN_RTR, uint8_t CAN_DLC, uint8_t *CAN_Data); void CAN_TTComModeCmd(FunctionalState NewState); CAN_TxStatus_TypeDef CAN_TransmitStatus(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox); void CAN_CancelTransmit(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox); void CAN_FIFORelease(void); CAN_NbrPendingMessage_TypeDef CAN_MessagePending(void); void CAN_Receive(void); uint32_t CAN_GetReceivedId(void); CAN_Id_TypeDef CAN_GetReceivedIDE(void); CAN_RTR_TypeDef CAN_GetReceivedRTR(void); uint8_t CAN_GetReceivedDLC(void); uint8_t CAN_GetReceivedData(uint8_t CAN_DataIndex); uint8_t CAN_GetReceivedFMI(void); uint16_t CAN_GetMessageTimeStamp(void); CAN_Sleep_TypeDef CAN_Sleep(void); CAN_WakeUp_TypeDef CAN_WakeUp(void); CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode); CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(void); CAN_Page_TypeDef CAN_GetSelectedPage(void); void CAN_SelectPage(CAN_Page_TypeDef CAN_Page); FlagStatus CAN_GetFlagStatus(CAN_FLAG_TypeDef CAN_Flag); void CAN_ClearFlag(CAN_FLAG_TypeDef CAN_Flag); ITStatus CAN_GetITStatus(CAN_IT_TypeDef CAN_IT); void CAN_ClearITPendingBit(CAN_IT_TypeDef CAN_IT); /** * @} */ #endif /* __STM8S_CAN_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_clk.h ================================================ /** ****************************************************************************** * @file stm8s_clk.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the CLK peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_CLK_H #define __STM8S_CLK_H /* Includes ------------------------------------------------------------------*/ /* Contains the description of all STM8 hardware registers */ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup CLK_Exported_Types * @{ */ /** * @brief Switch Mode Auto, Manual. */ typedef enum { CLK_SWITCHMODE_MANUAL = (uint8_t)0x00, /*!< Enable the manual clock switching mode */ CLK_SWITCHMODE_AUTO = (uint8_t)0x01 /*!< Enable the automatic clock switching mode */ } CLK_SwitchMode_TypeDef; /** * @brief Current Clock State. */ typedef enum { CLK_CURRENTCLOCKSTATE_DISABLE = (uint8_t)0x00, /*!< Current clock disable */ CLK_CURRENTCLOCKSTATE_ENABLE = (uint8_t)0x01 /*!< Current clock enable */ } CLK_CurrentClockState_TypeDef; /** * @brief Clock security system configuration. */ typedef enum { CLK_CSSCONFIG_ENABLEWITHIT = (uint8_t)0x05, /*!< Enable CSS with detection interrupt */ CLK_CSSCONFIG_ENABLE = (uint8_t)0x01, /*!< Enable CSS without detection interrupt */ CLK_CSSCONFIG_DISABLE = (uint8_t)0x00 /*!< Leave CSS desactivated (to be used in CLK_Init() function) */ } CLK_CSSConfig_TypeDef; /** * @brief CLK Clock Source. */ typedef enum { CLK_SOURCE_HSI = (uint8_t)0xE1, /*!< Clock Source HSI. */ CLK_SOURCE_LSI = (uint8_t)0xD2, /*!< Clock Source LSI. */ CLK_SOURCE_HSE = (uint8_t)0xB4 /*!< Clock Source HSE. */ } CLK_Source_TypeDef; /** * @brief CLK HSI Calibration Value. */ typedef enum { CLK_HSITRIMVALUE_0 = (uint8_t)0x00, /*!< HSI Calibration Value 0 */ CLK_HSITRIMVALUE_1 = (uint8_t)0x01, /*!< HSI Calibration Value 1 */ CLK_HSITRIMVALUE_2 = (uint8_t)0x02, /*!< HSI Calibration Value 2 */ CLK_HSITRIMVALUE_3 = (uint8_t)0x03, /*!< HSI Calibration Value 3 */ CLK_HSITRIMVALUE_4 = (uint8_t)0x04, /*!< HSI Calibration Value 4 */ CLK_HSITRIMVALUE_5 = (uint8_t)0x05, /*!< HSI Calibration Value 5 */ CLK_HSITRIMVALUE_6 = (uint8_t)0x06, /*!< HSI Calibration Value 6 */ CLK_HSITRIMVALUE_7 = (uint8_t)0x07 /*!< HSI Calibration Value 7 */ } CLK_HSITrimValue_TypeDef; /** * @brief CLK Clock Output */ typedef enum { CLK_OUTPUT_HSI = (uint8_t)0x00, /*!< Clock Output HSI */ CLK_OUTPUT_LSI = (uint8_t)0x02, /*!< Clock Output LSI */ CLK_OUTPUT_HSE = (uint8_t)0x04, /*!< Clock Output HSE */ CLK_OUTPUT_CPU = (uint8_t)0x08, /*!< Clock Output CPU */ CLK_OUTPUT_CPUDIV2 = (uint8_t)0x0A, /*!< Clock Output CPU/2 */ CLK_OUTPUT_CPUDIV4 = (uint8_t)0x0C, /*!< Clock Output CPU/4 */ CLK_OUTPUT_CPUDIV8 = (uint8_t)0x0E, /*!< Clock Output CPU/8 */ CLK_OUTPUT_CPUDIV16 = (uint8_t)0x10, /*!< Clock Output CPU/16 */ CLK_OUTPUT_CPUDIV32 = (uint8_t)0x12, /*!< Clock Output CPU/32 */ CLK_OUTPUT_CPUDIV64 = (uint8_t)0x14, /*!< Clock Output CPU/64 */ CLK_OUTPUT_HSIRC = (uint8_t)0x16, /*!< Clock Output HSI RC */ CLK_OUTPUT_MASTER = (uint8_t)0x18, /*!< Clock Output Master */ CLK_OUTPUT_OTHERS = (uint8_t)0x1A /*!< Clock Output OTHER */ } CLK_Output_TypeDef; /** * @brief CLK Enable peripheral */ /* Elements values convention: 0xXY X = choice between the peripheral registers X = 0 : PCKENR1 X = 1 : PCKENR2 Y = Peripheral position in the register */ typedef enum { CLK_PERIPHERAL_I2C = (uint8_t)0x00, /*!< Peripheral Clock Enable 1, I2C */ CLK_PERIPHERAL_SPI = (uint8_t)0x01, /*!< Peripheral Clock Enable 1, SPI */ #if defined(STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8AF52Ax) || defined(STM8AF62Ax) CLK_PERIPHERAL_UART1 = (uint8_t)0x02, /*!< Peripheral Clock Enable 1, UART1 */ #else CLK_PERIPHERAL_UART1 = (uint8_t)0x03, /*!< Peripheral Clock Enable 1, UART1 */ #endif CLK_PERIPHERAL_UART2 = (uint8_t)0x03, /*!< Peripheral Clock Enable 1, UART2 */ CLK_PERIPHERAL_UART3 = (uint8_t)0x03, /*!< Peripheral Clock Enable 1, UART3 */ CLK_PERIPHERAL_TIMER6 = (uint8_t)0x04, /*!< Peripheral Clock Enable 1, Timer6 */ CLK_PERIPHERAL_TIMER4 = (uint8_t)0x04, /*!< Peripheral Clock Enable 1, Timer4 */ CLK_PERIPHERAL_TIMER5 = (uint8_t)0x05, /*!< Peripheral Clock Enable 1, Timer5 */ CLK_PERIPHERAL_TIMER2 = (uint8_t)0x05, /*!< Peripheral Clock Enable 1, Timer2 */ CLK_PERIPHERAL_TIMER3 = (uint8_t)0x06, /*!< Peripheral Clock Enable 1, Timer3 */ CLK_PERIPHERAL_TIMER1 = (uint8_t)0x07, /*!< Peripheral Clock Enable 1, Timer1 */ CLK_PERIPHERAL_AWU = (uint8_t)0x12, /*!< Peripheral Clock Enable 2, AWU */ CLK_PERIPHERAL_ADC = (uint8_t)0x13, /*!< Peripheral Clock Enable 2, ADC */ CLK_PERIPHERAL_CAN = (uint8_t)0x17 /*!< Peripheral Clock Enable 2, CAN */ } CLK_Peripheral_TypeDef; /** * @brief CLK Flags. */ /* Elements values convention: 0xXZZ X = choice between the flags registers X = 1 : ICKR X = 2 : ECKR X = 3 : SWCR X = 4 : CSSR X = 5 : CCOR ZZ = flag mask in the register (same as map file) */ typedef enum { CLK_FLAG_LSIRDY = (uint16_t)0x0110, /*!< Low speed internal oscillator ready Flag */ CLK_FLAG_HSIRDY = (uint16_t)0x0102, /*!< High speed internal oscillator ready Flag */ CLK_FLAG_HSERDY = (uint16_t)0x0202, /*!< High speed external oscillator ready Flag */ CLK_FLAG_SWIF = (uint16_t)0x0308, /*!< Clock switch interrupt Flag */ CLK_FLAG_SWBSY = (uint16_t)0x0301, /*!< Switch busy Flag */ CLK_FLAG_CSSD = (uint16_t)0x0408, /*!< Clock security system detection Flag */ CLK_FLAG_AUX = (uint16_t)0x0402, /*!< Auxiliary oscillator connected to master clock */ CLK_FLAG_CCOBSY = (uint16_t)0x0504, /*!< Configurable clock output busy */ CLK_FLAG_CCORDY = (uint16_t)0x0502 /*!< Configurable clock output ready */ }CLK_Flag_TypeDef; /** * @brief CLK interrupt configuration and Flags cleared by software. */ typedef enum { CLK_IT_CSSD = (uint8_t)0x0C, /*!< Clock security system detection Flag */ CLK_IT_SWIF = (uint8_t)0x1C /*!< Clock switch interrupt Flag */ }CLK_IT_TypeDef; /** * @brief CLK Clock Divisor. */ /* Warning: 0xxxxxx = HSI divider 1xxxxxx = CPU divider Other bits correspond to the divider's bits mapping */ typedef enum { CLK_PRESCALER_HSIDIV1 = (uint8_t)0x00, /*!< High speed internal clock prescaler: 1 */ CLK_PRESCALER_HSIDIV2 = (uint8_t)0x08, /*!< High speed internal clock prescaler: 2 */ CLK_PRESCALER_HSIDIV4 = (uint8_t)0x10, /*!< High speed internal clock prescaler: 4 */ CLK_PRESCALER_HSIDIV8 = (uint8_t)0x18, /*!< High speed internal clock prescaler: 8 */ CLK_PRESCALER_CPUDIV1 = (uint8_t)0x80, /*!< CPU clock division factors 1 */ CLK_PRESCALER_CPUDIV2 = (uint8_t)0x81, /*!< CPU clock division factors 2 */ CLK_PRESCALER_CPUDIV4 = (uint8_t)0x82, /*!< CPU clock division factors 4 */ CLK_PRESCALER_CPUDIV8 = (uint8_t)0x83, /*!< CPU clock division factors 8 */ CLK_PRESCALER_CPUDIV16 = (uint8_t)0x84, /*!< CPU clock division factors 16 */ CLK_PRESCALER_CPUDIV32 = (uint8_t)0x85, /*!< CPU clock division factors 32 */ CLK_PRESCALER_CPUDIV64 = (uint8_t)0x86, /*!< CPU clock division factors 64 */ CLK_PRESCALER_CPUDIV128 = (uint8_t)0x87 /*!< CPU clock division factors 128 */ } CLK_Prescaler_TypeDef; /** * @brief SWIM Clock divider. */ typedef enum { CLK_SWIMDIVIDER_2 = (uint8_t)0x00, /*!< SWIM clock is divided by 2 */ CLK_SWIMDIVIDER_OTHER = (uint8_t)0x01 /*!< SWIM clock is not divided by 2 */ }CLK_SWIMDivider_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /** @addtogroup CLK_Exported_Constants * @{ */ #define CLK_TIMEOUT ((uint16_t)0xFFFF) /*!< Max Timeout for the clock switch operation. */ /** * @} */ /* Private macros ------------------------------------------------------------*/ /** @addtogroup CLK_Private_Macros * @{ */ /** * @brief Macros used by the assert function in order to check the different functions parameters. */ /** * @brief Macros used by the assert function in order to check the clock switching modes. */ #define IS_CLK_SWITCHMODE_OK(MODE) (((MODE) == CLK_SWITCHMODE_MANUAL) || ((MODE) == CLK_SWITCHMODE_AUTO)) /** * @brief Macros used by the assert function in order to check the current clock state. */ #define IS_CLK_CURRENTCLOCKSTATE_OK(STATE) (((STATE) == CLK_CURRENTCLOCKSTATE_DISABLE) ||\ ((STATE) == CLK_CURRENTCLOCKSTATE_ENABLE)) /** * @brief Macros used by the assert function in order to check the CSS configuration. */ #define IS_CLK_CSSCONFIG_OK(CSSVALUE) (((CSSVALUE) == CLK_CSSCONFIG_ENABLEWITHIT) ||\ ((CSSVALUE) == CLK_CSSCONFIG_ENABLE) ||\ ((CSSVALUE) == CLK_CSSCONFIG_DISABLE)) /** * @brief Macros used by the assert function in order to check the different clock sources. */ #define IS_CLK_SOURCE_OK(SOURCE) (((SOURCE) == CLK_SOURCE_HSI) ||\ ((SOURCE) == CLK_SOURCE_LSI) ||\ ((SOURCE) == CLK_SOURCE_HSE)) /** * @brief Macros used by the assert function in order to check the different HSI trimming values. */ #define IS_CLK_HSITRIMVALUE_OK(TRIMVALUE) (((TRIMVALUE) == CLK_HSITRIMVALUE_0) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_1) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_2) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_3) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_4) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_5) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_6) ||\ ((TRIMVALUE) == CLK_HSITRIMVALUE_7)) /** * @brief Macros used by the assert function in order to check the different clocks to output. */ #define IS_CLK_OUTPUT_OK(OUTPUT) (((OUTPUT) == CLK_OUTPUT_HSI) ||\ ((OUTPUT) == CLK_OUTPUT_HSE) ||\ ((OUTPUT) == CLK_OUTPUT_LSI) ||\ ((OUTPUT) == CLK_OUTPUT_CPU) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV2) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV4) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV8) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV16) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV32) ||\ ((OUTPUT) == CLK_OUTPUT_CPUDIV64) ||\ ((OUTPUT) == CLK_OUTPUT_HSIRC) ||\ ((OUTPUT) == CLK_OUTPUT_MASTER) ||\ ((OUTPUT) == CLK_OUTPUT_OTHERS)) /** * @brief Macros used by the assert function in order to check the different peripheral's clock. */ #define IS_CLK_PERIPHERAL_OK(PERIPHERAL) (((PERIPHERAL) == CLK_PERIPHERAL_I2C) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_SPI) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_UART3) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_UART2) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_UART1) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER4) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER2) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER5) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER6) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER3) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_TIMER1) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_CAN) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_ADC) ||\ ((PERIPHERAL) == CLK_PERIPHERAL_AWU)) /** * @brief Macros used by the assert function in order to check the different clock flags. */ #define IS_CLK_FLAG_OK(FLAG) (((FLAG) == CLK_FLAG_LSIRDY) ||\ ((FLAG) == CLK_FLAG_HSIRDY) ||\ ((FLAG) == CLK_FLAG_HSERDY) ||\ ((FLAG) == CLK_FLAG_SWIF) ||\ ((FLAG) == CLK_FLAG_SWBSY) ||\ ((FLAG) == CLK_FLAG_CSSD) ||\ ((FLAG) == CLK_FLAG_AUX) ||\ ((FLAG) == CLK_FLAG_CCOBSY) ||\ ((FLAG) == CLK_FLAG_CCORDY)) /** * @brief Macros used by the assert function in order to check the different clock IT pending bits. */ #define IS_CLK_IT_OK(IT) (((IT) == CLK_IT_CSSD) || ((IT) == CLK_IT_SWIF)) /** * @brief Macros used by the assert function in order to check the different HSI prescaler values. */ #define IS_CLK_HSIPRESCALER_OK(PRESCALER) (((PRESCALER) == CLK_PRESCALER_HSIDIV1) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV2) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV4) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV8)) /** * @brief Macros used by the assert function in order to check the different clock prescaler values. */ #define IS_CLK_PRESCALER_OK(PRESCALER) (((PRESCALER) == CLK_PRESCALER_HSIDIV1) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV2) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV4) ||\ ((PRESCALER) == CLK_PRESCALER_HSIDIV8) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV1) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV2) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV4) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV8) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV16) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV32) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV64) ||\ ((PRESCALER) == CLK_PRESCALER_CPUDIV128)) /** * @brief Macros used by the assert function in order to check the different SWIM dividers values. */ #define IS_CLK_SWIMDIVIDER_OK(SWIMDIVIDER) (((SWIMDIVIDER) == CLK_SWIMDIVIDER_2) || ((SWIMDIVIDER) == CLK_SWIMDIVIDER_OTHER)) /** * @} */ /** @addtogroup CLK_Exported_functions * @{ */ void CLK_DeInit(void); void CLK_HSECmd(FunctionalState NewState); void CLK_HSICmd(FunctionalState NewState); void CLK_LSICmd(FunctionalState NewState); void CLK_CCOCmd(FunctionalState NewState); void CLK_ClockSwitchCmd(FunctionalState NewState); void CLK_FastHaltWakeUpCmd(FunctionalState NewState); void CLK_SlowActiveHaltWakeUpCmd(FunctionalState NewState); void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral, FunctionalState NewState); ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState); void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler); void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO); void CLK_ITConfig(CLK_IT_TypeDef CLK_IT, FunctionalState NewState); void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef CLK_Prescaler); void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider); void CLK_ClockSecuritySystemEnable(void); void CLK_SYSCLKEmergencyClear(void); void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSICalibrationValue); uint32_t CLK_GetClockFreq(void); CLK_Source_TypeDef CLK_GetSYSCLKSource(void); FlagStatus CLK_GetFlagStatus(CLK_Flag_TypeDef CLK_FLAG); ITStatus CLK_GetITStatus(CLK_IT_TypeDef CLK_IT); void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT); /** * @} */ #endif /* __STM8S_CLK_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_exti.h ================================================ /** ****************************************************************************** * @file stm8s_exti.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the EXTI peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_EXTI_H #define __STM8S_EXTI_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup EXTI_Exported_Types * @{ */ /** * @brief EXTI Sensitivity values for PORTA to PORTE */ typedef enum { EXTI_SENSITIVITY_FALL_LOW = (uint8_t)0x00, /*!< Interrupt on Falling edge and Low level */ EXTI_SENSITIVITY_RISE_ONLY = (uint8_t)0x01, /*!< Interrupt on Rising edge only */ EXTI_SENSITIVITY_FALL_ONLY = (uint8_t)0x02, /*!< Interrupt on Falling edge only */ EXTI_SENSITIVITY_RISE_FALL = (uint8_t)0x03 /*!< Interrupt on Rising and Falling edges */ } EXTI_Sensitivity_TypeDef; /** * @brief EXTI Sensitivity values for TLI */ typedef enum { EXTI_TLISENSITIVITY_FALL_ONLY = (uint8_t)0x00, /*!< Top Level Interrupt on Falling edge only */ EXTI_TLISENSITIVITY_RISE_ONLY = (uint8_t)0x04 /*!< Top Level Interrupt on Rising edge only */ } EXTI_TLISensitivity_TypeDef; /** * @brief EXTI PortNum possible values */ typedef enum { EXTI_PORT_GPIOA = (uint8_t)0x00, /*!< GPIO Port A */ EXTI_PORT_GPIOB = (uint8_t)0x01, /*!< GPIO Port B */ EXTI_PORT_GPIOC = (uint8_t)0x02, /*!< GPIO Port C */ EXTI_PORT_GPIOD = (uint8_t)0x03, /*!< GPIO Port D */ EXTI_PORT_GPIOE = (uint8_t)0x04 /*!< GPIO Port E */ } EXTI_Port_TypeDef; /** * @} */ /* Private macros ------------------------------------------------------------*/ /** @addtogroup EXTI_Private_Macros * @{ */ /** * @brief Macro used by the assert function in order to check the different sensitivity values for PORTA to PORTE. */ #define IS_EXTI_SENSITIVITY_OK(SensitivityValue) \ (((SensitivityValue) == EXTI_SENSITIVITY_FALL_LOW) || \ ((SensitivityValue) == EXTI_SENSITIVITY_RISE_ONLY) || \ ((SensitivityValue) == EXTI_SENSITIVITY_FALL_ONLY) || \ ((SensitivityValue) == EXTI_SENSITIVITY_RISE_FALL)) /** * @brief Macro used by the assert function in order to check the different sensitivity values for TLI. */ #define IS_EXTI_TLISENSITIVITY_OK(SensitivityValue) \ (((SensitivityValue) == EXTI_TLISENSITIVITY_FALL_ONLY) || \ ((SensitivityValue) == EXTI_TLISENSITIVITY_RISE_ONLY)) /** * @brief Macro used by the assert function in order to check the different Port values */ #define IS_EXTI_PORT_OK(PORT) \ (((PORT) == EXTI_PORT_GPIOA) ||\ ((PORT) == EXTI_PORT_GPIOB) ||\ ((PORT) == EXTI_PORT_GPIOC) ||\ ((PORT) == EXTI_PORT_GPIOD) ||\ ((PORT) == EXTI_PORT_GPIOE)) /** * @brief Macro used by the assert function in order to check the different values of the EXTI PinMask */ #define IS_EXTI_PINMASK_OK(PinMask) ((((PinMask) & (uint8_t)0x00) == (uint8_t)0x00) && ((PinMask) != (uint8_t)0x00)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup EXTI_Exported_Functions * @{ */ void EXTI_DeInit(void); void EXTI_SetExtIntSensitivity(EXTI_Port_TypeDef Port, EXTI_Sensitivity_TypeDef SensitivityValue); void EXTI_SetTLISensitivity(EXTI_TLISensitivity_TypeDef SensitivityValue); EXTI_Sensitivity_TypeDef EXTI_GetExtIntSensitivity(EXTI_Port_TypeDef Port); EXTI_TLISensitivity_TypeDef EXTI_GetTLISensitivity(void); /** * @} */ #endif /* __STM8S_EXTI_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_flash.h ================================================ /** ****************************************************************************** * @file stm8s_flash.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the FLASH peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_FLASH_H #define __STM8S_FLASH_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported constants --------------------------------------------------------*/ /** @addtogroup FLASH_Exported_Constants * @{ */ #define FLASH_PROG_START_PHYSICAL_ADDRESS ((uint32_t)0x008000) /*!< Program memory: start address */ #if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined (STM8AF52Ax) || defined (STM8AF62Ax) #define FLASH_PROG_END_PHYSICAL_ADDRESS ((uint32_t)0x027FFF) /*!< Program memory: end address */ #define FLASH_PROG_BLOCKS_NUMBER ((uint16_t)1024) /*!< Program memory: total number of blocks */ #define FLASH_DATA_START_PHYSICAL_ADDRESS ((uint32_t)0x004000) /*!< Data EEPROM memory: start address */ #define FLASH_DATA_END_PHYSICAL_ADDRESS ((uint32_t)0x0047FF) /*!< Data EEPROM memory: end address */ #define FLASH_DATA_BLOCKS_NUMBER ((uint16_t)16) /*!< Data EEPROM memory: total number of blocks */ #define FLASH_BLOCK_SIZE ((uint8_t)128) /*!< Number of bytes in a block (common for Program and Data memories) */ #endif /* STM8S208, STM8S207, STM8S007, STM8AF52Ax, STM8AF62Ax */ #if defined(STM8S105) || defined(STM8S005) || defined(STM8AF626x) #define FLASH_PROG_END_PHYSICAL_ADDRESS ((uint32_t)0xFFFF) /*!< Program memory: end address */ #define FLASH_PROG_BLOCKS_NUMBER ((uint16_t)256) /*!< Program memory: total number of blocks */ #define FLASH_DATA_START_PHYSICAL_ADDRESS ((uint32_t)0x004000) /*!< Data EEPROM memory: start address */ #define FLASH_DATA_END_PHYSICAL_ADDRESS ((uint32_t)0x0043FF) /*!< Data EEPROM memory: end address */ #define FLASH_DATA_BLOCKS_NUMBER ((uint16_t)8) /*!< Data EEPROM memory: total number of blocks */ #define FLASH_BLOCK_SIZE ((uint8_t)128) /*!< Number of bytes in a block (common for Program and Data memories) */ #endif /* STM8S105 or STM8AF626x */ #if defined(STM8S103) || defined(STM8S003) || defined(STM8S001) || defined(STM8S903) || defined(STM8AF622x) #define FLASH_PROG_END_PHYSICAL_ADDRESS ((uint32_t)0x9FFF) /*!< Program memory: end address */ #define FLASH_PROG_BLOCKS_NUMBER ((uint16_t)128) /*!< Program memory: total number of blocks */ #define FLASH_DATA_START_PHYSICAL_ADDRESS ((uint32_t)0x004000) /*!< Data EEPROM memory: start address */ #define FLASH_DATA_END_PHYSICAL_ADDRESS ((uint32_t)0x00427F) /*!< Data EEPROM memory: end address */ #define FLASH_DATA_BLOCKS_NUMBER ((uint16_t)10) /*!< Data EEPROM memory: total number of blocks */ #define FLASH_BLOCK_SIZE ((uint8_t)64) /*!< Number of bytes in a block (common for Program and Data memories) */ #endif /* STM8S103 or STM8S003 or STM8S001 or STM8S903 or STM8AF622x*/ #define FLASH_RASS_KEY1 ((uint8_t)0x56) /*!< First RASS key */ #define FLASH_RASS_KEY2 ((uint8_t)0xAE) /*!< Second RASS key */ #define OPTION_BYTE_START_PHYSICAL_ADDRESS ((uint16_t)0x4800) #define OPTION_BYTE_END_PHYSICAL_ADDRESS ((uint16_t)0x487F) #define FLASH_OPTIONBYTE_ERROR ((uint16_t)0x5555) /*!< Error code option byte (if value read is not equal to complement value read) */ /** * @} */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup FLASH_Exported_Types * @{ */ /** * @brief FLASH Memory types */ typedef enum { FLASH_MEMTYPE_PROG = (uint8_t)0xFD, /*!< Program memory */ FLASH_MEMTYPE_DATA = (uint8_t)0xF7 /*!< Data EEPROM memory */ } FLASH_MemType_TypeDef; /** * @brief FLASH programming modes */ typedef enum { FLASH_PROGRAMMODE_STANDARD = (uint8_t)0x00, /*!< Standard programming mode */ FLASH_PROGRAMMODE_FAST = (uint8_t)0x10 /*!< Fast programming mode */ } FLASH_ProgramMode_TypeDef; /** * @brief FLASH fixed programming time */ typedef enum { FLASH_PROGRAMTIME_STANDARD = (uint8_t)0x00, /*!< Standard programming time fixed at 1/2 tprog */ FLASH_PROGRAMTIME_TPROG = (uint8_t)0x01 /*!< Programming time fixed at tprog */ } FLASH_ProgramTime_TypeDef; /** * @brief FLASH Low Power mode select */ typedef enum { FLASH_LPMODE_POWERDOWN = (uint8_t)0x04, /*!< HALT: Power-Down / ACTIVE-HALT: Power-Down */ FLASH_LPMODE_STANDBY = (uint8_t)0x08, /*!< HALT: Standby / ACTIVE-HALT: Standby */ FLASH_LPMODE_POWERDOWN_STANDBY = (uint8_t)0x00, /*!< HALT: Power-Down / ACTIVE-HALT: Standby */ FLASH_LPMODE_STANDBY_POWERDOWN = (uint8_t)0x0C /*!< HALT: Standby / ACTIVE-HALT: Power-Down */ } FLASH_LPMode_TypeDef; /** * @brief FLASH status of the last operation */ typedef enum { #if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ defined(STM8S005) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined(STM8AF626x) FLASH_STATUS_END_HIGH_VOLTAGE = (uint8_t)0x40, /*!< End of high voltage */ #endif /* STM8S208, STM8S207, STM8S105, STM8AF62Ax, STM8AF52Ax, STM8AF626x */ FLASH_STATUS_SUCCESSFUL_OPERATION = (uint8_t)0x04, /*!< End of operation flag */ FLASH_STATUS_TIMEOUT = (uint8_t)0x02, /*!< Time out error */ FLASH_STATUS_WRITE_PROTECTION_ERROR = (uint8_t)0x01 /*!< Write attempted to protected page */ } FLASH_Status_TypeDef; /** * @brief FLASH flags definition * - Warning : FLAG value = mapping position register */ typedef enum { #if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ defined(STM8S005) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined(STM8AF626x) FLASH_FLAG_HVOFF = (uint8_t)0x40, /*!< End of high voltage flag */ #endif /* STM8S208, STM8S207, STM8S105, STM8AF62Ax, STM8AF52Ax, STM8AF626x */ FLASH_FLAG_DUL = (uint8_t)0x08, /*!< Data EEPROM unlocked flag */ FLASH_FLAG_EOP = (uint8_t)0x04, /*!< End of programming (write or erase operation) flag */ FLASH_FLAG_PUL = (uint8_t)0x02, /*!< Flash Program memory unlocked flag */ FLASH_FLAG_WR_PG_DIS = (uint8_t)0x01 /*!< Write attempted to protected page flag */ } FLASH_Flag_TypeDef; /** * @} */ /* Private macros ------------------------------------------------------------*/ /** * @brief Macros used by the assert function in order to check the different functions parameters. * @addtogroup FLASH_Private_Macros * @{ */ /** * @brief Macro used by the assert function in order to check the different sensitivity values for the flash program Address */ #define IS_FLASH_PROG_ADDRESS_OK(ADDRESS) (((ADDRESS) >= FLASH_PROG_START_PHYSICAL_ADDRESS) && \ ((ADDRESS) <= FLASH_PROG_END_PHYSICAL_ADDRESS)) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the data eeprom Address */ #define IS_FLASH_DATA_ADDRESS_OK(ADDRESS) (((ADDRESS) >= FLASH_DATA_START_PHYSICAL_ADDRESS) && \ ((ADDRESS) <= FLASH_DATA_END_PHYSICAL_ADDRESS)) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the data eeprom and flash program Address */ #define IS_FLASH_ADDRESS_OK(ADDRESS)((((ADDRESS) >= FLASH_PROG_START_PHYSICAL_ADDRESS) && ((ADDRESS) <= FLASH_PROG_END_PHYSICAL_ADDRESS)) || \ (((ADDRESS) >= FLASH_DATA_START_PHYSICAL_ADDRESS) && ((ADDRESS) <= FLASH_DATA_END_PHYSICAL_ADDRESS))) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the flash program Block number */ #define IS_FLASH_PROG_BLOCK_NUMBER_OK(BLOCKNUM) ((BLOCKNUM) < FLASH_PROG_BLOCKS_NUMBER) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the data eeprom Block number */ #define IS_FLASH_DATA_BLOCK_NUMBER_OK(BLOCKNUM) ((BLOCKNUM) < FLASH_DATA_BLOCKS_NUMBER) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the flash memory type */ #define IS_MEMORY_TYPE_OK(MEMTYPE) (((MEMTYPE) == FLASH_MEMTYPE_PROG) || \ ((MEMTYPE) == FLASH_MEMTYPE_DATA)) /** * @brief Macro used by the assert function in order to check the different sensitivity values for the flash program mode */ #define IS_FLASH_PROGRAM_MODE_OK(MODE) (((MODE) == FLASH_PROGRAMMODE_STANDARD) || \ ((MODE) == FLASH_PROGRAMMODE_FAST)) /** * @brief Macro used by the assert function in order to check the program time mode */ #define IS_FLASH_PROGRAM_TIME_OK(TIME) (((TIME) == FLASH_PROGRAMTIME_STANDARD) || \ ((TIME) == FLASH_PROGRAMTIME_TPROG)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the low power mode */ #define IS_FLASH_LOW_POWER_MODE_OK(LPMODE) (((LPMODE) == FLASH_LPMODE_POWERDOWN) || \ ((LPMODE) == FLASH_LPMODE_STANDBY) || \ ((LPMODE) == FLASH_LPMODE_POWERDOWN_STANDBY) || \ ((LPMODE) == FLASH_LPMODE_STANDBY_POWERDOWN)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the option bytes Address */ #define IS_OPTION_BYTE_ADDRESS_OK(ADDRESS) (((ADDRESS) >= OPTION_BYTE_START_PHYSICAL_ADDRESS) && \ ((ADDRESS) <= OPTION_BYTE_END_PHYSICAL_ADDRESS)) /** * @brief Macro used by the assert function in order to check the different flags values */ #if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ defined(STM8S005) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined(STM8AF626x) #define IS_FLASH_FLAGS_OK(FLAG) (((FLAG) == FLASH_FLAG_HVOFF) || \ ((FLAG) == FLASH_FLAG_DUL) || \ ((FLAG) == FLASH_FLAG_EOP) || \ ((FLAG) == FLASH_FLAG_PUL) || \ ((FLAG) == FLASH_FLAG_WR_PG_DIS)) #else /* STM8S103, STM8S001, STM8S903, STM8AF622x */ #define IS_FLASH_FLAGS_OK(FLAG) (((FLAG) == FLASH_FLAG_DUL) || \ ((FLAG) == FLASH_FLAG_EOP) || \ ((FLAG) == FLASH_FLAG_PUL) || \ ((FLAG) == FLASH_FLAG_WR_PG_DIS)) #endif /* STM8S208, STM8S207, STM8S105, STM8AF62Ax, STM8AF52Ax, STM8AF626x */ /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup FLASH_Exported_Functions * @{ */ void FLASH_Unlock(FLASH_MemType_TypeDef FLASH_MemType); void FLASH_Lock(FLASH_MemType_TypeDef FLASH_MemType); void FLASH_DeInit(void); void FLASH_ITConfig(FunctionalState NewState); void FLASH_EraseByte(uint32_t Address); void FLASH_ProgramByte(uint32_t Address, uint8_t Data); uint8_t FLASH_ReadByte(uint32_t Address); void FLASH_ProgramWord(uint32_t Address, uint32_t Data); uint16_t FLASH_ReadOptionByte(uint16_t Address); void FLASH_ProgramOptionByte(uint16_t Address, uint8_t Data); void FLASH_EraseOptionByte(uint16_t Address); void FLASH_SetLowPowerMode(FLASH_LPMode_TypeDef FLASH_LPMode); void FLASH_SetProgrammingTime(FLASH_ProgramTime_TypeDef FLASH_ProgTime); FLASH_LPMode_TypeDef FLASH_GetLowPowerMode(void); FLASH_ProgramTime_TypeDef FLASH_GetProgrammingTime(void); uint32_t FLASH_GetBootSize(void); FlagStatus FLASH_GetFlagStatus(FLASH_Flag_TypeDef FLASH_FLAG); /** @code All the functions declared below must be executed from RAM exclusively, except for the FLASH_WaitForLastOperation function which can be executed from Flash. Steps of the execution from RAM differs from one toolchain to another. for more details refer to stm8s_flash.c file. To enable execution from RAM you can either uncomment the following define in the stm8s.h file or define it in your toolchain compiler preprocessor - #define RAM_EXECUTION (1) @endcode */ IN_RAM(void FLASH_EraseBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType)); IN_RAM(void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType, FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer)); IN_RAM(FLASH_Status_TypeDef FLASH_WaitForLastOperation(FLASH_MemType_TypeDef FLASH_MemType)); /** * @} */ #endif /*__STM8S_FLASH_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_gpio.h ================================================ /** ****************************************************************************** * @file stm8s_gpio.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the GPIO peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_GPIO_H #define __STM8S_GPIO_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported variables ------------------------------------------------------- */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup GPIO_Exported_Types * @{ */ /** * @brief GPIO modes * * Bits definitions: * - Bit 7: 0 = INPUT mode * 1 = OUTPUT mode * 1 = PULL-UP (input) or PUSH-PULL (output) * - Bit 5: 0 = No external interrupt (input) or No slope control (output) * 1 = External interrupt (input) or Slow control enabled (output) * - Bit 4: 0 = Low level (output) * 1 = High level (output push-pull) or HI-Z (output open-drain) */ typedef enum { GPIO_MODE_IN_FL_NO_IT = (uint8_t)0x00, /*!< Input floating, no external interrupt */ GPIO_MODE_IN_PU_NO_IT = (uint8_t)0x40, /*!< Input pull-up, no external interrupt */ GPIO_MODE_IN_FL_IT = (uint8_t)0x20, /*!< Input floating, external interrupt */ GPIO_MODE_IN_PU_IT = (uint8_t)0x60, /*!< Input pull-up, external interrupt */ GPIO_MODE_OUT_OD_LOW_FAST = (uint8_t)0xA0, /*!< Output open-drain, low level, 10MHz */ GPIO_MODE_OUT_PP_LOW_FAST = (uint8_t)0xE0, /*!< Output push-pull, low level, 10MHz */ GPIO_MODE_OUT_OD_LOW_SLOW = (uint8_t)0x80, /*!< Output open-drain, low level, 2MHz */ GPIO_MODE_OUT_PP_LOW_SLOW = (uint8_t)0xC0, /*!< Output push-pull, low level, 2MHz */ GPIO_MODE_OUT_OD_HIZ_FAST = (uint8_t)0xB0, /*!< Output open-drain, high-impedance level,10MHz */ GPIO_MODE_OUT_PP_HIGH_FAST = (uint8_t)0xF0, /*!< Output push-pull, high level, 10MHz */ GPIO_MODE_OUT_OD_HIZ_SLOW = (uint8_t)0x90, /*!< Output open-drain, high-impedance level, 2MHz */ GPIO_MODE_OUT_PP_HIGH_SLOW = (uint8_t)0xD0 /*!< Output push-pull, high level, 2MHz */ }GPIO_Mode_TypeDef; /** * @brief Definition of the GPIO pins. Used by the @ref GPIO_Init function in * order to select the pins to be initialized. */ typedef enum { GPIO_PIN_0 = ((uint8_t)0x01), /*!< Pin 0 selected */ GPIO_PIN_1 = ((uint8_t)0x02), /*!< Pin 1 selected */ GPIO_PIN_2 = ((uint8_t)0x04), /*!< Pin 2 selected */ GPIO_PIN_3 = ((uint8_t)0x08), /*!< Pin 3 selected */ GPIO_PIN_4 = ((uint8_t)0x10), /*!< Pin 4 selected */ GPIO_PIN_5 = ((uint8_t)0x20), /*!< Pin 5 selected */ GPIO_PIN_6 = ((uint8_t)0x40), /*!< Pin 6 selected */ GPIO_PIN_7 = ((uint8_t)0x80), /*!< Pin 7 selected */ GPIO_PIN_LNIB = ((uint8_t)0x0F), /*!< Low nibble pins selected */ GPIO_PIN_HNIB = ((uint8_t)0xF0), /*!< High nibble pins selected */ GPIO_PIN_ALL = ((uint8_t)0xFF) /*!< All pins selected */ }GPIO_Pin_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup GPIO_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert function in order to check the different * values of GPIOMode_TypeDef. */ #define IS_GPIO_MODE_OK(MODE) \ (((MODE) == GPIO_MODE_IN_FL_NO_IT) || \ ((MODE) == GPIO_MODE_IN_PU_NO_IT) || \ ((MODE) == GPIO_MODE_IN_FL_IT) || \ ((MODE) == GPIO_MODE_IN_PU_IT) || \ ((MODE) == GPIO_MODE_OUT_OD_LOW_FAST) || \ ((MODE) == GPIO_MODE_OUT_PP_LOW_FAST) || \ ((MODE) == GPIO_MODE_OUT_OD_LOW_SLOW) || \ ((MODE) == GPIO_MODE_OUT_PP_LOW_SLOW) || \ ((MODE) == GPIO_MODE_OUT_OD_HIZ_FAST) || \ ((MODE) == GPIO_MODE_OUT_PP_HIGH_FAST) || \ ((MODE) == GPIO_MODE_OUT_OD_HIZ_SLOW) || \ ((MODE) == GPIO_MODE_OUT_PP_HIGH_SLOW)) /** * @brief Macro used by the assert function in order to check the different * values of GPIO_Pins. */ #define IS_GPIO_PIN_OK(PIN) ((PIN) != (uint8_t)0x00) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup GPIO_Exported_Functions * @{ */ void GPIO_DeInit(GPIO_TypeDef* GPIOx); void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode); void GPIO_Write(GPIO_TypeDef* GPIOx, uint8_t PortVal); void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); uint8_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); uint8_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin); void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState); /** * @} */ #endif /* __STM8L_GPIO_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_i2c.h ================================================ /** ****************************************************************************** * @file stm8s_i2c.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the I2C peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_I2C_H #define __STM8S_I2C_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup I2C_Exported_Types * @{ */ /** * @brief I2C duty cycle (fast mode only) */ typedef enum { I2C_DUTYCYCLE_2 = (uint8_t)0x00, /*!< Fast mode Tlow/THigh = 2 */ I2C_DUTYCYCLE_16_9 = (uint8_t)0x40 /*!< Fast mode Tlow/Thigh = 16/9 */ } I2C_DutyCycle_TypeDef; /** * @brief I2C Acknowledgement configuration */ typedef enum { I2C_ACK_NONE = (uint8_t)0x00, /*!< No acknowledge */ I2C_ACK_CURR = (uint8_t)0x01, /*!< Acknowledge on the current byte */ I2C_ACK_NEXT = (uint8_t)0x02 /*!< Acknowledge on the next byte */ } I2C_Ack_TypeDef; /** * @brief I2C Addressing Mode (slave mode only) */ typedef enum { I2C_ADDMODE_7BIT = (uint8_t)0x00, /*!< 7-bit slave address (10-bit address not acknowledged) */ I2C_ADDMODE_10BIT = (uint8_t)0x80 /*!< 10-bit slave address (7-bit address not acknowledged) */ } I2C_AddMode_TypeDef; /** * @brief I2C Interrupt sources * Warning: the values correspond to the bit position in the ITR register */ typedef enum { I2C_IT_ERR = (uint8_t)0x01, /*!< Error Interruption */ I2C_IT_EVT = (uint8_t)0x02, /*!< Event Interruption */ I2C_IT_BUF = (uint8_t)0x04 /*!< Buffer Interruption */ } I2C_IT_TypeDef; /** * @brief I2C transfer direction * Warning: the values correspond to the ADD0 bit position in the OARL register */ typedef enum { I2C_DIRECTION_TX = (uint8_t)0x00, /*!< Transmission direction */ I2C_DIRECTION_RX = (uint8_t)0x01 /*!< Reception direction */ } I2C_Direction_TypeDef; /** * @brief I2C Flags * @brief Elements values convention: 0xXXYY * X = SRx registers index * X = 1 : SR1 * X = 2 : SR2 * X = 3 : SR3 * Y = Flag mask in the register */ typedef enum { /* SR1 register flags */ I2C_FLAG_TXEMPTY = (uint16_t)0x0180, /*!< Transmit Data Register Empty flag */ I2C_FLAG_RXNOTEMPTY = (uint16_t)0x0140, /*!< Read Data Register Not Empty flag */ I2C_FLAG_STOPDETECTION = (uint16_t)0x0110, /*!< Stop detected flag */ I2C_FLAG_HEADERSENT = (uint16_t)0x0108, /*!< 10-bit Header sent flag */ I2C_FLAG_TRANSFERFINISHED = (uint16_t)0x0104, /*!< Data Byte Transfer Finished flag */ I2C_FLAG_ADDRESSSENTMATCHED = (uint16_t)0x0102, /*!< Address Sent/Matched (master/slave) flag */ I2C_FLAG_STARTDETECTION = (uint16_t)0x0101, /*!< Start bit sent flag */ /* SR2 register flags */ I2C_FLAG_WAKEUPFROMHALT = (uint16_t)0x0220, /*!< Wake Up From Halt Flag */ I2C_FLAG_OVERRUNUNDERRUN = (uint16_t)0x0208, /*!< Overrun/Underrun flag */ I2C_FLAG_ACKNOWLEDGEFAILURE = (uint16_t)0x0204, /*!< Acknowledge Failure Flag */ I2C_FLAG_ARBITRATIONLOSS = (uint16_t)0x0202, /*!< Arbitration Loss Flag */ I2C_FLAG_BUSERROR = (uint16_t)0x0201, /*!< Misplaced Start or Stop condition */ /* SR3 register flags */ I2C_FLAG_GENERALCALL = (uint16_t)0x0310, /*!< General Call header received Flag */ I2C_FLAG_TRANSMITTERRECEIVER = (uint16_t)0x0304, /*!< Transmitter Receiver Flag */ I2C_FLAG_BUSBUSY = (uint16_t)0x0302, /*!< Bus Busy Flag */ I2C_FLAG_MASTERSLAVE = (uint16_t)0x0301 /*!< Master Slave Flag */ } I2C_Flag_TypeDef; /** * @brief I2C Pending bits * Elements values convention: 0xXYZZ * X = SRx registers index * X = 1 : SR1 * X = 2 : SR2 * Y = Position of the corresponding Interrupt * ZZ = flag mask in the dedicated register(X register) */ typedef enum { /* SR1 register flags */ I2C_ITPENDINGBIT_TXEMPTY = (uint16_t)0x1680, /*!< Transmit Data Register Empty */ I2C_ITPENDINGBIT_RXNOTEMPTY = (uint16_t)0x1640, /*!< Read Data Register Not Empty */ I2C_ITPENDINGBIT_STOPDETECTION = (uint16_t)0x1210, /*!< Stop detected */ I2C_ITPENDINGBIT_HEADERSENT = (uint16_t)0x1208, /*!< 10-bit Header sent */ I2C_ITPENDINGBIT_TRANSFERFINISHED = (uint16_t)0x1204, /*!< Data Byte Transfer Finished */ I2C_ITPENDINGBIT_ADDRESSSENTMATCHED = (uint16_t)0x1202, /*!< Address Sent/Matched (master/slave) */ I2C_ITPENDINGBIT_STARTDETECTION = (uint16_t)0x1201, /*!< Start bit sent */ /* SR2 register flags */ I2C_ITPENDINGBIT_WAKEUPFROMHALT = (uint16_t)0x2220, /*!< Wake Up From Halt */ I2C_ITPENDINGBIT_OVERRUNUNDERRUN = (uint16_t)0x2108, /*!< Overrun/Underrun */ I2C_ITPENDINGBIT_ACKNOWLEDGEFAILURE = (uint16_t)0x2104, /*!< Acknowledge Failure */ I2C_ITPENDINGBIT_ARBITRATIONLOSS = (uint16_t)0x2102, /*!< Arbitration Loss */ I2C_ITPENDINGBIT_BUSERROR = (uint16_t)0x2101 /*!< Misplaced Start or Stop condition */ } I2C_ITPendingBit_TypeDef; /** * @brief I2C possible events * Values convention: 0xXXYY * XX = Event SR3 corresponding value * YY = Event SR1 corresponding value * @note if Event = EV3_2 the rule above does not apply * YY = Event SR2 corresponding value */ typedef enum { /*======================================== I2C Master Events (Events grouped in order of communication) ==========================================*/ /** * @brief Communication start * * After sending the START condition (I2C_GenerateSTART() function) the master * has to wait for this event. It means that the Start condition has been correctly * released on the I2C bus (the bus is free, no other devices is communicating). * */ /* --EV5 */ I2C_EVENT_MASTER_MODE_SELECT = (uint16_t)0x0301, /*!< BUSY, MSL and SB flag */ /** * @brief Address Acknowledge * * After checking on EV5 (start condition correctly released on the bus), the * master sends the address of the slave(s) with which it will communicate * (I2C_Send7bitAddress() function, it also determines the direction of the communication: * Master transmitter or Receiver). * Then the master has to wait that a slave acknowledges his address. * If an acknowledge is sent on the bus, one of the following events will * be set: * * 1) In case of Master Receiver (7-bit addressing): * the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED event is set. * * 2) In case of Master Transmitter (7-bit addressing): * the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED is set * * 3) In case of 10-Bit addressing mode, the master (just after generating the START * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() * function). * Then master should wait on EV9. It means that the 10-bit addressing * header has been correctly sent on the bus. * Then master should send the second part of the 10-bit address (LSB) using * the function I2C_Send7bitAddress(). Then master should wait for event EV6. * */ /* --EV6 */ I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED = (uint16_t)0x0782, /*!< BUSY, MSL, ADDR, TXE and TRA flags */ I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED = (uint16_t)0x0302, /*!< BUSY, MSL and ADDR flags */ /* --EV9 */ I2C_EVENT_MASTER_MODE_ADDRESS10 = (uint16_t)0x0308, /*!< BUSY, MSL and ADD10 flags */ /** * @brief Communication events * * If a communication is established (START condition generated and slave address * acknowledged) then the master has to check on one of the following events for * communication procedures: * * 1) Master Receiver mode: The master has to wait on the event EV7 then to read * the data received from the slave (I2C_ReceiveData() function). * * 2) Master Transmitter mode: The master has to send data (I2C_SendData() * function) then to wait on event EV8 or EV8_2. * These two events are similar: * - EV8 means that the data has been written in the data register and is * being shifted out. * - EV8_2 means that the data has been physically shifted out and output * on the bus. * In most cases, using EV8 is sufficient for the application. * Using EV8_2 leads to a slower communication but ensures more reliable test. * EV8_2 is also more suitable than EV8 for testing on the last data transmission * (before Stop condition generation). * * @note In case the user software does not guarantee that this event EV7 is * managed before the current byte end of transfer, then user may check on EV7 * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). * In this case the communication may be slower. * */ /* Master RECEIVER mode -----------------------------*/ /* --EV7 */ I2C_EVENT_MASTER_BYTE_RECEIVED = (uint16_t)0x0340, /*!< BUSY, MSL and RXNE flags */ /* Master TRANSMITTER mode --------------------------*/ /* --EV8 */ I2C_EVENT_MASTER_BYTE_TRANSMITTING = (uint16_t)0x0780, /*!< TRA, BUSY, MSL, TXE flags */ /* --EV8_2 */ I2C_EVENT_MASTER_BYTE_TRANSMITTED = (uint16_t)0x0784, /*!< EV8_2: TRA, BUSY, MSL, TXE and BTF flags */ /*======================================== I2C Slave Events (Events grouped in order of communication) ==========================================*/ /** * @brief Communication start events * * Wait on one of these events at the start of the communication. It means that * the I2C peripheral detected a Start condition on the bus (generated by master * device) followed by the peripheral address. * The peripheral generates an ACK condition on the bus (if the acknowledge * feature is enabled through function I2C_AcknowledgeConfig()) and the events * listed above are set : * * 1) In normal case (only one address managed by the slave), when the address * sent by the master matches the own address of the peripheral (configured by * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set * (where XXX could be TRANSMITTER or RECEIVER). * * 2) In case the address sent by the master is General Call (address 0x00) and * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. * */ /* --EV1 (all the events below are variants of EV1) */ /* 1) Case of One Single Address managed by the slave */ I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED = (uint16_t)0x0202, /*!< BUSY and ADDR flags */ I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED = (uint16_t)0x0682, /*!< TRA, BUSY, TXE and ADDR flags */ /* 2) Case of General Call enabled for the slave */ I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED = (uint16_t)0x1200, /*!< EV2: GENCALL and BUSY flags */ /** * @brief Communication events * * Wait on one of these events when EV1 has already been checked : * * - Slave RECEIVER mode: * - EV2: When the application is expecting a data byte to be received. * - EV4: When the application is expecting the end of the communication: * master sends a stop condition and data transmission is stopped. * * - Slave Transmitter mode: * - EV3: When a byte has been transmitted by the slave and the application * is expecting the end of the byte transmission. * The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and I2C_EVENT_SLAVE_BYTE_TRANSMITTING * are similar. The second one can optionally be used when the user software * doesn't guarantee the EV3 is managed before the current byte end of transfer. * - EV3_2: When the master sends a NACK in order to tell slave that data transmission * shall end (before sending the STOP condition). * In this case slave has to stop sending data bytes and expect a Stop * condition on the bus. * * @note In case the user software does not guarantee that the event EV2 is * managed before the current byte end of transfer, then user may check on EV2 * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). * In this case the communication may be slower. * */ /* Slave RECEIVER mode --------------------------*/ /* --EV2 */ I2C_EVENT_SLAVE_BYTE_RECEIVED = (uint16_t)0x0240, /*!< BUSY and RXNE flags */ /* --EV4 */ I2C_EVENT_SLAVE_STOP_DETECTED = (uint16_t)0x0010, /*!< STOPF flag */ /* Slave TRANSMITTER mode -----------------------*/ /* --EV3 */ I2C_EVENT_SLAVE_BYTE_TRANSMITTED = (uint16_t)0x0684, /*!< TRA, BUSY, TXE and BTF flags */ I2C_EVENT_SLAVE_BYTE_TRANSMITTING = (uint16_t)0x0680, /*!< TRA, BUSY and TXE flags */ /* --EV3_2 */ I2C_EVENT_SLAVE_ACK_FAILURE = (uint16_t)0x0004 /*!< AF flag */ } I2C_Event_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /** @addtogroup I2C_Exported_Constants * @{ */ #define I2C_MAX_STANDARD_FREQ ((uint32_t)100000) #define I2C_MAX_FAST_FREQ ((uint32_t)400000) #if defined(STM8S208) || defined(STM8S207) || defined(STM8S007) #define I2C_MAX_INPUT_FREQ ((uint8_t)24) #else #define I2C_MAX_INPUT_FREQ ((uint8_t)16) #endif /** * @} */ /* Exported macros -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup I2C_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert function to check the different I2C duty cycles. */ #define IS_I2C_DUTYCYCLE_OK(DUTY) \ (((DUTY) == I2C_DUTYCYCLE_2) || \ ((DUTY) == I2C_DUTYCYCLE_16_9)) /** * @brief Macro used by the assert function to check the different acknowledgement configuration */ #define IS_I2C_ACK_OK(ACK) \ (((ACK) == I2C_ACK_NONE) || \ ((ACK) == I2C_ACK_CURR) || \ ((ACK) == I2C_ACK_NEXT)) /** * @brief Macro used by the assert function to check the different I2C addressing modes. */ #define IS_I2C_ADDMODE_OK(ADDMODE) \ (((ADDMODE) == I2C_ADDMODE_7BIT) || \ ((ADDMODE) == I2C_ADDMODE_10BIT)) /** * @brief Macro used by the assert function to check the different I2C interrupt types. */ #define IS_I2C_INTERRUPT_OK(IT) \ (((IT) == I2C_IT_ERR) || \ ((IT) == I2C_IT_EVT) || \ ((IT) == I2C_IT_BUF) || \ ((IT) == (I2C_IT_ERR | I2C_IT_EVT)) || \ ((IT) == (I2C_IT_ERR | I2C_IT_BUF)) || \ ((IT) == (I2C_IT_EVT | I2C_IT_BUF)) || \ ((IT) == (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR))) /** * @brief Macro used by the assert function to check the different I2C communcation direction. */ #define IS_I2C_DIRECTION_OK(DIR) \ (((DIR) == I2C_DIRECTION_TX) || \ ((DIR) == I2C_DIRECTION_RX)) /** * @brief Macro used by the assert function to check the different I2C flags. */ #define IS_I2C_FLAG_OK(FLAG) \ (((FLAG) == I2C_FLAG_TXEMPTY) || \ ((FLAG) == I2C_FLAG_RXNOTEMPTY) || \ ((FLAG) == I2C_FLAG_STOPDETECTION) || \ ((FLAG) == I2C_FLAG_HEADERSENT) || \ ((FLAG) == I2C_FLAG_TRANSFERFINISHED) || \ ((FLAG) == I2C_FLAG_ADDRESSSENTMATCHED) || \ ((FLAG) == I2C_FLAG_STARTDETECTION) || \ ((FLAG) == I2C_FLAG_WAKEUPFROMHALT) || \ ((FLAG) == I2C_FLAG_OVERRUNUNDERRUN) || \ ((FLAG) == I2C_FLAG_ACKNOWLEDGEFAILURE) || \ ((FLAG) == I2C_FLAG_ARBITRATIONLOSS) || \ ((FLAG) == I2C_FLAG_BUSERROR) || \ ((FLAG) == I2C_FLAG_GENERALCALL) || \ ((FLAG) == I2C_FLAG_TRANSMITTERRECEIVER) || \ ((FLAG) == I2C_FLAG_BUSBUSY) || \ ((FLAG) == I2C_FLAG_MASTERSLAVE)) /** * @brief Macro used by the assert function to check the I2C flags to clear. */ #define IS_I2C_CLEAR_FLAG_OK(FLAG) ((((uint16_t)(FLAG) & (uint16_t)0xFD00) == 0x00) \ && ((uint16_t)(FLAG) != 0x00)) /** * @brief Macro used by the assert function to check the different I2C possible pending bits. */ #define IS_I2C_ITPENDINGBIT_OK(ITPENDINGBIT) \ (((ITPENDINGBIT) == I2C_ITPENDINGBIT_TXEMPTY) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_RXNOTEMPTY) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_STOPDETECTION) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_HEADERSENT) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_TRANSFERFINISHED) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_ADDRESSSENTMATCHED) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_STARTDETECTION) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_WAKEUPFROMHALT) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_OVERRUNUNDERRUN) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_ACKNOWLEDGEFAILURE) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_ARBITRATIONLOSS) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_BUSERROR)) /** * @brief Macro used by the assert function to check the different I2C possible * pending bits to clear by writing 0. */ #define IS_I2C_CLEAR_ITPENDINGBIT_OK(ITPENDINGBIT) \ (((ITPENDINGBIT) == I2C_ITPENDINGBIT_WAKEUPFROMHALT) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_OVERRUNUNDERRUN) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_ACKNOWLEDGEFAILURE) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_ARBITRATIONLOSS) || \ ((ITPENDINGBIT) == I2C_ITPENDINGBIT_BUSERROR)) /** * @brief Macro used by the assert function to check the different I2C possible events. */ #define IS_I2C_EVENT_OK(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | (uint16_t)I2C_FLAG_GENERALCALL)) || \ ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | (uint16_t)I2C_FLAG_GENERALCALL)) || \ ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE) || \ ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10)) /** * @brief Macro used by the assert function to check the different I2C possible own address. */ #define IS_I2C_OWN_ADDRESS_OK(ADDRESS) \ ((ADDRESS) <= (uint16_t)0x03FF) /* The address must be even */ #define IS_I2C_ADDRESS_OK(ADD) \ (((ADD) & (uint8_t)0x01) == (uint8_t)0x00) /** * @brief Macro used by the assert function to check that I2C Input clock frequency must be between 1MHz and 50MHz. */ #define IS_I2C_INPUT_CLOCK_FREQ_OK(FREQ) \ (((FREQ) >= (uint8_t)1) && ((FREQ) <= I2C_MAX_INPUT_FREQ)) /** * @brief Macro used by the assert function to check that I2C Output clock frequency must be between 1Hz and 400kHz. */ #define IS_I2C_OUTPUT_CLOCK_FREQ_OK(FREQ) \ (((FREQ) >= (uint8_t)1) && ((FREQ) <= I2C_MAX_FAST_FREQ)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup I2C_Exported_Functions * @{ */ void I2C_DeInit(void); void I2C_Init(uint32_t OutputClockFrequencyHz, uint16_t OwnAddress, I2C_DutyCycle_TypeDef I2C_DutyCycle, I2C_Ack_TypeDef Ack, I2C_AddMode_TypeDef AddMode, uint8_t InputClockFrequencyMHz ); void I2C_Cmd(FunctionalState NewState); void I2C_GeneralCallCmd(FunctionalState NewState); void I2C_GenerateSTART(FunctionalState NewState); void I2C_GenerateSTOP(FunctionalState NewState); void I2C_SoftwareResetCmd(FunctionalState NewState); void I2C_StretchClockCmd(FunctionalState NewState); void I2C_AcknowledgeConfig(I2C_Ack_TypeDef Ack); void I2C_FastModeDutyCycleConfig(I2C_DutyCycle_TypeDef I2C_DutyCycle); void I2C_ITConfig(I2C_IT_TypeDef I2C_IT, FunctionalState NewState); uint8_t I2C_ReceiveData(void); void I2C_Send7bitAddress(uint8_t Address, I2C_Direction_TypeDef Direction); void I2C_SendData(uint8_t Data); /** * @brief **************************************************************************************** * * I2C State Monitoring Functions * **************************************************************************************** * This I2C driver provides three different ways for I2C state monitoring * depending on the application requirements and constraints: * * * 1) Basic state monitoring: * Using I2C_CheckEvent() function: * It compares the status registers (SR1, SR2 and SR3) content to a given event * (can be the combination of one or more flags). * It returns SUCCESS if the current status includes the given flags * and returns ERROR if one or more flags are missing in the current status. * - When to use: * - This function is suitable for most applications as well as for startup * activity since the events are fully described in the product reference manual * (RM0016). * - It is also suitable for users who need to define their own events. * - Limitations: * - If an error occurs (ie. error flags are set besides to the monitored flags), * the I2C_CheckEvent() function may return SUCCESS despite the communication * hold or corrupted real state. * In this case, it is advised to use error interrupts to monitor the error * events and handle them in the interrupt IRQ handler. * * @note * For error management, it is advised to use the following functions: * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). * - I2C_IRQHandler() which is called when the I2C interrupts occur. * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the * I2Cx_IRQHandler() function in order to determine which error occurred. * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() * and/or I2C_GenerateStop() in order to clear the error flag and * source and return to correct communication status. * * * 2) Advanced state monitoring: * Using the function I2C_GetLastEvent() which returns the image of both SR1 * & SR3 status registers in a single word (uint16_t) (Status Register 3 value * is shifted left by 8 bits and concatenated to Status Register 1). * - When to use: * - This function is suitable for the same applications above but it allows to * overcome the limitations of I2C_GetFlagStatus() function (see below). * The returned value could be compared to events already defined in the * library (stm8s_i2c.h) or to custom values defined by user. * - This function is suitable when multiple flags are monitored at the same time. * - At the opposite of I2C_CheckEvent() function, this function allows user to * choose when an event is accepted (when all events flags are set and no * other flags are set or just when the needed flags are set like * I2C_CheckEvent() function). * - Limitations: * - User may need to define his own events. * - Same remark concerning the error management is applicable for this * function if user decides to check only regular communication flags (and * ignores error flags). * * * 3) Flag-based state monitoring: * Using the function I2C_GetFlagStatus() which simply returns the status of * one single flag (ie. I2C_FLAG_RXNE ...). * - When to use: * - This function could be used for specific applications or in debug phase. * - It is suitable when only one flag checking is needed (most I2C events * are monitored through multiple flags). * - Limitations: * - When calling this function, the Status register is accessed. Some flags are * cleared when the status register is accessed. So checking the status * of one Flag, may clear other ones. * - Function may need to be called twice or more in order to monitor one * single event. * */ /** * * 1) Basic state monitoring ******************************************************************************* */ ErrorStatus I2C_CheckEvent(I2C_Event_TypeDef I2C_Event); /** * * 2) Advanced state monitoring ******************************************************************************* */ I2C_Event_TypeDef I2C_GetLastEvent(void); /** * * 3) Flag-based state monitoring ******************************************************************************* */ FlagStatus I2C_GetFlagStatus(I2C_Flag_TypeDef I2C_Flag); /** * ******************************************************************************* */ void I2C_ClearFlag(I2C_Flag_TypeDef I2C_FLAG); ITStatus I2C_GetITStatus(I2C_ITPendingBit_TypeDef I2C_ITPendingBit); void I2C_ClearITPendingBit(I2C_ITPendingBit_TypeDef I2C_ITPendingBit); /** * @} */ #endif /* __STM8S_I2C_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_itc.h ================================================ /** ****************************************************************************** * @file stm8s_itc.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the ITC peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_ITC_H #define __STM8S_ITC_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /* Exported types ------------------------------------------------------------*/ /** @addtogroup ITC_Exported_Types * @{ */ /** * @brief ITC Interrupt Lines selection */ typedef enum { ITC_IRQ_TLI = (uint8_t)0, /*!< Software interrupt */ ITC_IRQ_AWU = (uint8_t)1, /*!< Auto wake up from halt interrupt */ ITC_IRQ_CLK = (uint8_t)2, /*!< Clock controller interrupt */ ITC_IRQ_PORTA = (uint8_t)3, /*!< Port A external interrupts */ ITC_IRQ_PORTB = (uint8_t)4, /*!< Port B external interrupts */ ITC_IRQ_PORTC = (uint8_t)5, /*!< Port C external interrupts */ ITC_IRQ_PORTD = (uint8_t)6, /*!< Port D external interrupts */ ITC_IRQ_PORTE = (uint8_t)7, /*!< Port E external interrupts */ #if defined(STM8S208) || defined(STM8AF52Ax) ITC_IRQ_CAN_RX = (uint8_t)8, /*!< beCAN RX interrupt */ ITC_IRQ_CAN_TX = (uint8_t)9, /*!< beCAN TX/ER/SC interrupt */ #endif /*STM8S208 or STM8AF52Ax */ #if defined(STM8S903) || defined(STM8AF622x) ITC_IRQ_PORTF = (uint8_t)8, /*!< Port F external interrupts */ #endif /*STM8S903 or STM8AF622x */ ITC_IRQ_SPI = (uint8_t)10, /*!< SPI interrupt */ ITC_IRQ_TIM1_OVF = (uint8_t)11, /*!< TIM1 update/overflow/underflow/trigger/ break interrupt*/ ITC_IRQ_TIM1_CAPCOM = (uint8_t)12, /*!< TIM1 capture/compare interrupt */ #if defined(STM8S903) || defined(STM8AF622x) ITC_IRQ_TIM5_OVFTRI = (uint8_t)13, /*!< TIM5 update/overflow/underflow/trigger/ interrupt */ ITC_IRQ_TIM5_CAPCOM = (uint8_t)14, /*!< TIM5 capture/compare interrupt */ #else ITC_IRQ_TIM2_OVF = (uint8_t)13, /*!< TIM2 update /overflow interrupt */ ITC_IRQ_TIM2_CAPCOM = (uint8_t)14, /*!< TIM2 capture/compare interrupt */ #endif /*STM8S903 or STM8AF622x */ ITC_IRQ_TIM3_OVF = (uint8_t)15, /*!< TIM3 update /overflow interrupt*/ ITC_IRQ_TIM3_CAPCOM = (uint8_t)16, /*!< TIM3 update /overflow interrupt */ #if defined(STM8S208) ||defined(STM8S207) || defined (STM8S007) || defined(STM8S103) || \ defined(STM8S003) || defined(STM8S001) ||defined(STM8S903) || defined (STM8AF52Ax) || defined (STM8AF62Ax) ITC_IRQ_UART1_TX = (uint8_t)17, /*!< UART1 TX interrupt */ ITC_IRQ_UART1_RX = (uint8_t)18, /*!< UART1 RX interrupt */ #endif /*STM8S208 or STM8S207 or STM8S007 or STM8S103 or STM8S003 or STM8S001 or STM8S903 or STM8AF52Ax or STM8AF62Ax */ #if defined(STM8AF622x) ITC_IRQ_UART4_TX = (uint8_t)17, /*!< UART4 TX interrupt */ ITC_IRQ_UART4_RX = (uint8_t)18, /*!< UART4 RX interrupt */ #endif /*STM8AF622x */ ITC_IRQ_I2C = (uint8_t)19, /*!< I2C interrupt */ #if defined(STM8S105) || defined(STM8S005) || defined(STM8AF626x) ITC_IRQ_UART2_TX = (uint8_t)20, /*!< USART2 TX interrupt */ ITC_IRQ_UART2_RX = (uint8_t)21, /*!< USART2 RX interrupt */ #endif /*STM8S105 or STM8AF626x */ #if defined(STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8AF52Ax) || defined(STM8AF62Ax) ITC_IRQ_UART3_TX = (uint8_t)20, /*!< USART3 TX interrupt */ ITC_IRQ_UART3_RX = (uint8_t)21, /*!< USART3 RX interrupt */ ITC_IRQ_ADC2 = (uint8_t)22, /*!< ADC2 interrupt */ #endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */ #if defined(STM8S105) || defined(STM8S005) || defined(STM8S103) || defined(STM8S003) || defined(STM8S001) || defined(STM8S903) || defined(STM8AF626x) || defined(STM8AF622x) ITC_IRQ_ADC1 = (uint8_t)22, /*!< ADC1 interrupt */ #endif /*STM8S105 or STM8S005 or STM8S003 or STM8S103 or STM8S001 or STM8S903 or STM8AF626x or STM8AF622x */ #if defined(STM8S903) || defined(STM8AF622x) ITC_IRQ_TIM6_OVFTRI = (uint8_t)23, /*!< TIM6 update/overflow/underflow/trigger/ interrupt */ #else ITC_IRQ_TIM4_OVF = (uint8_t)23, /*!< TIM4 update /overflow interrupt */ #endif /*STM8S903 or STM8AF622x */ ITC_IRQ_EEPROM_EEC = (uint8_t)24 /*!< Flash interrupt */ } ITC_Irq_TypeDef; /** * @brief ITC Priority Levels selection */ typedef enum { ITC_PRIORITYLEVEL_0 = (uint8_t)0x02, /*!< Software priority level 0 (cannot be written) */ ITC_PRIORITYLEVEL_1 = (uint8_t)0x01, /*!< Software priority level 1 */ ITC_PRIORITYLEVEL_2 = (uint8_t)0x00, /*!< Software priority level 2 */ ITC_PRIORITYLEVEL_3 = (uint8_t)0x03 /*!< Software priority level 3 */ } ITC_PriorityLevel_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /** @addtogroup ITC_Exported_Constants * @{ */ #define CPU_SOFT_INT_DISABLED ((uint8_t)0x28) /*!< Mask for I1 and I0 bits in CPU_CC register */ /** * @} */ /* Private macros ------------------------------------------------------------*/ /** * @brief Macros used by the assert function in order to check the different functions parameters. * @addtogroup ITC_Private_Macros * @{ */ /* Used by assert function */ #define IS_ITC_IRQ_OK(IRQ) ((IRQ) <= (uint8_t)24) /* Used by assert function */ #define IS_ITC_PRIORITY_OK(PriorityValue) \ (((PriorityValue) == ITC_PRIORITYLEVEL_0) || \ ((PriorityValue) == ITC_PRIORITYLEVEL_1) || \ ((PriorityValue) == ITC_PRIORITYLEVEL_2) || \ ((PriorityValue) == ITC_PRIORITYLEVEL_3)) /* Used by assert function */ #define IS_ITC_INTERRUPTS_DISABLED (ITC_GetSoftIntStatus() == CPU_SOFT_INT_DISABLED) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup ITC_Exported_Functions * @{ */ uint8_t ITC_GetCPUCC(void); void ITC_DeInit(void); uint8_t ITC_GetSoftIntStatus(void); void ITC_SetSoftwarePriority(ITC_Irq_TypeDef IrqNum, ITC_PriorityLevel_TypeDef PriorityValue); ITC_PriorityLevel_TypeDef ITC_GetSoftwarePriority(ITC_Irq_TypeDef IrqNum); /** * @} */ #endif /* __STM8S_ITC_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_iwdg.h ================================================ /** ****************************************************************************** * @file stm8s_iwdg.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototypes and macros for the IWDG peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_IWDG_H #define __STM8S_IWDG_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /** @addtogroup IWDG_Private_Define * @{ */ /** * @brief Define used to prevent watchdog reset */ #define IWDG_KEY_REFRESH ((uint8_t)0xAA) /*!< This value written in the Key register prevent the watchdog reset */ /** * @brief Define used to start the watchdog counter down */ #define IWDG_KEY_ENABLE ((uint8_t)0xCC) /*!< This value written in the Key register start the watchdog counting down*/ /** * @} */ /** @addtogroup IWDG_Private_Macros * @{ */ /** * @brief Macro used by the assert function in order to check the different * values of the prescaler. */ #define IS_IWDG_PRESCALER_OK(VALUE) (((VALUE) == IWDG_Prescaler_4 ) || \ ((VALUE) == IWDG_Prescaler_8 ) || \ ((VALUE) == IWDG_Prescaler_16 ) || \ ((VALUE) == IWDG_Prescaler_32 ) || \ ((VALUE) == IWDG_Prescaler_64 ) || \ ((VALUE) == IWDG_Prescaler_128 ) || \ ((VALUE) == IWDG_Prescaler_256)) /** * @brief Macro used by the assert function in order to check the different * values of the counter register. */ #define IS_IWDG_WRITEACCESS_MODE_OK(MODE) (((MODE) == IWDG_WriteAccess_Enable) || ((MODE) == IWDG_WriteAccess_Disable)) /** * @} */ /** @addtogroup IWDG_Exported_Types * @{ */ /** IWDG write access enumeration */ typedef enum { IWDG_WriteAccess_Enable = (uint8_t)0x55, /*!< Code 0x55 in Key register, allow write access to Prescaler and Reload registers */ IWDG_WriteAccess_Disable = (uint8_t)0x00 /*!< Code 0x00 in Key register, not allow write access to Prescaler and Reload registers */ } IWDG_WriteAccess_TypeDef; /** IWDG prescaler enumaration */ typedef enum { IWDG_Prescaler_4 = (uint8_t)0x00, /*!< Used to set prescaler register to 4 */ IWDG_Prescaler_8 = (uint8_t)0x01, /*!< Used to set prescaler register to 8 */ IWDG_Prescaler_16 = (uint8_t)0x02, /*!< Used to set prescaler register to 16 */ IWDG_Prescaler_32 = (uint8_t)0x03, /*!< Used to set prescaler register to 32 */ IWDG_Prescaler_64 = (uint8_t)0x04, /*!< Used to set prescaler register to 64 */ IWDG_Prescaler_128 = (uint8_t)0x05, /*!< Used to set prescaler register to 128 */ IWDG_Prescaler_256 = (uint8_t)0x06 /*!< Used to set prescaler register to 256 */ } IWDG_Prescaler_TypeDef; /** * @} */ /** @addtogroup IWDG_Exported_Functions * @{ */ void IWDG_WriteAccessCmd(IWDG_WriteAccess_TypeDef IWDG_WriteAccess); void IWDG_SetPrescaler(IWDG_Prescaler_TypeDef IWDG_Prescaler); void IWDG_SetReload(uint8_t IWDG_Reload); void IWDG_ReloadCounter(void); void IWDG_Enable(void); /** * @} */ #endif /* __STM8S_IWDG_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_rst.h ================================================ /** ****************************************************************************** * @file stm8s_rst.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the RST peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_RST_H #define __STM8S_RST_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /** @addtogroup RST_Exported_Types * @{ */ typedef enum { RST_FLAG_EMCF = (uint8_t)0x10, /*!< EMC reset flag */ RST_FLAG_SWIMF = (uint8_t)0x08, /*!< SWIM reset flag */ RST_FLAG_ILLOPF = (uint8_t)0x04, /*!< Illigal opcode reset flag */ RST_FLAG_IWDGF = (uint8_t)0x02, /*!< Independent watchdog reset flag */ RST_FLAG_WWDGF = (uint8_t)0x01 /*!< Window watchdog reset flag */ }RST_Flag_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /** @addtogroup RST_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert function to check the different RST flags. */ #define IS_RST_FLAG_OK(FLAG) (((FLAG) == RST_FLAG_EMCF) || \ ((FLAG) == RST_FLAG_SWIMF) ||\ ((FLAG) == RST_FLAG_ILLOPF) ||\ ((FLAG) == RST_FLAG_IWDGF) ||\ ((FLAG) == RST_FLAG_WWDGF)) /** * @} */ /** @addtogroup RST_Exported_functions * @{ */ FlagStatus RST_GetFlagStatus(RST_Flag_TypeDef RST_Flag); void RST_ClearFlag(RST_Flag_TypeDef RST_Flag); /** * @} */ #endif /* __STM8S_RST_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_spi.h ================================================ /** ****************************************************************************** * @file stm8s_spi.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the SPI peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_SPI_H #define __STM8S_SPI_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /** @addtogroup SPI_Exported_Types * @{ */ /** * @brief SPI data direction mode * Warning: element values correspond to BDM, BDOE, RXONLY bits position */ typedef enum { SPI_DATADIRECTION_2LINES_FULLDUPLEX = (uint8_t)0x00, /*!< 2-line uni-directional data mode enable */ SPI_DATADIRECTION_2LINES_RXONLY = (uint8_t)0x04, /*!< Receiver only in 2 line uni-directional data mode */ SPI_DATADIRECTION_1LINE_RX = (uint8_t)0x80, /*!< Receiver only in 1 line bi-directional data mode */ SPI_DATADIRECTION_1LINE_TX = (uint8_t)0xC0 /*!< Transmit only in 1 line bi-directional data mode */ } SPI_DataDirection_TypeDef; /** * @brief SPI Slave Select management * Warning: element values correspond to LSBFIRST bit position */ typedef enum { SPI_NSS_SOFT = (uint8_t)0x02, /*!< Software slave management disabled */ SPI_NSS_HARD = (uint8_t)0x00 /*!< Software slave management enabled */ } SPI_NSS_TypeDef; /** * @brief SPI direction transmit/receive */ typedef enum { SPI_DIRECTION_RX = (uint8_t)0x00, /*!< Selects Rx receive direction in bi-directional mode */ SPI_DIRECTION_TX = (uint8_t)0x01 /*!< Selects Tx transmission direction in bi-directional mode */ } SPI_Direction_TypeDef; /** * @brief SPI master/slave mode * Warning: element values correspond to MSTR bit position */ typedef enum { SPI_MODE_MASTER = (uint8_t)0x04, /*!< SPI Master configuration */ SPI_MODE_SLAVE = (uint8_t)0x00 /*!< SPI Slave configuration */ } SPI_Mode_TypeDef; /** * @brief SPI BaudRate Prescaler * Warning: element values correspond to BR bits position */ typedef enum { SPI_BAUDRATEPRESCALER_2 = (uint8_t)0x00, /*!< SPI frequency = frequency(CPU)/2 */ SPI_BAUDRATEPRESCALER_4 = (uint8_t)0x08, /*!< SPI frequency = frequency(CPU)/4 */ SPI_BAUDRATEPRESCALER_8 = (uint8_t)0x10, /*!< SPI frequency = frequency(CPU)/8 */ SPI_BAUDRATEPRESCALER_16 = (uint8_t)0x18, /*!< SPI frequency = frequency(CPU)/16 */ SPI_BAUDRATEPRESCALER_32 = (uint8_t)0x20, /*!< SPI frequency = frequency(CPU)/32 */ SPI_BAUDRATEPRESCALER_64 = (uint8_t)0x28, /*!< SPI frequency = frequency(CPU)/64 */ SPI_BAUDRATEPRESCALER_128 = (uint8_t)0x30, /*!< SPI frequency = frequency(CPU)/128 */ SPI_BAUDRATEPRESCALER_256 = (uint8_t)0x38 /*!< SPI frequency = frequency(CPU)/256 */ } SPI_BaudRatePrescaler_TypeDef; /** * @brief SPI Clock Polarity * Warning: element values correspond to CPOL bit position */ typedef enum { SPI_CLOCKPOLARITY_LOW = (uint8_t)0x00, /*!< Clock to 0 when idle */ SPI_CLOCKPOLARITY_HIGH = (uint8_t)0x02 /*!< Clock to 1 when idle */ } SPI_ClockPolarity_TypeDef; /** * @brief SPI Clock Phase * Warning: element values correspond to CPHA bit position */ typedef enum { SPI_CLOCKPHASE_1EDGE = (uint8_t)0x00, /*!< The first clock transition is the first data capture edge */ SPI_CLOCKPHASE_2EDGE = (uint8_t)0x01 /*!< The second clock transition is the first data capture edge */ } SPI_ClockPhase_TypeDef; /** * @brief SPI Frame Format: MSB or LSB transmitted first * Warning: element values correspond to LSBFIRST bit position */ typedef enum { SPI_FIRSTBIT_MSB = (uint8_t)0x00, /*!< MSB bit will be transmitted first */ SPI_FIRSTBIT_LSB = (uint8_t)0x80 /*!< LSB bit will be transmitted first */ } SPI_FirstBit_TypeDef; /** * @brief SPI CRC Transmit/Receive */ typedef enum { SPI_CRC_RX = (uint8_t)0x00, /*!< Select Tx CRC register */ SPI_CRC_TX = (uint8_t)0x01 /*!< Select Rx CRC register */ } SPI_CRC_TypeDef; /** * @brief SPI flags definition - Warning : FLAG value = mapping position register */ typedef enum { SPI_FLAG_BSY = (uint8_t)0x80, /*!< Busy flag */ SPI_FLAG_OVR = (uint8_t)0x40, /*!< Overrun flag */ SPI_FLAG_MODF = (uint8_t)0x20, /*!< Mode fault */ SPI_FLAG_CRCERR = (uint8_t)0x10, /*!< CRC error flag */ SPI_FLAG_WKUP = (uint8_t)0x08, /*!< Wake-up flag */ SPI_FLAG_TXE = (uint8_t)0x02, /*!< Transmit buffer empty */ SPI_FLAG_RXNE = (uint8_t)0x01 /*!< Receive buffer empty */ } SPI_Flag_TypeDef; /** * @brief SPI_IT possible values * Elements values convention: 0xYX * X: Position of the corresponding Interrupt * Y: ITPENDINGBIT position */ typedef enum { SPI_IT_WKUP = (uint8_t)0x34, /*!< Wake-up interrupt*/ SPI_IT_OVR = (uint8_t)0x65, /*!< Overrun interrupt*/ SPI_IT_MODF = (uint8_t)0x55, /*!< Mode fault interrupt*/ SPI_IT_CRCERR = (uint8_t)0x45, /*!< CRC error interrupt*/ SPI_IT_TXE = (uint8_t)0x17, /*!< Transmit buffer empty interrupt*/ SPI_IT_RXNE = (uint8_t)0x06, /*!< Receive buffer not empty interrupt*/ SPI_IT_ERR = (uint8_t)0x05 /*!< Error interrupt*/ } SPI_IT_TypeDef; /** * @} */ /* Private define ------------------------------------------------------------*/ /** @addtogroup SPI_Private_Macros * @brief Macros used by the assert_param function to check the different functions parameters. * @{ */ /** * @brief Macro used by the assert_param function in order to check the data direction mode values */ #define IS_SPI_DATA_DIRECTION_OK(MODE) (((MODE) == SPI_DATADIRECTION_2LINES_FULLDUPLEX) || \ ((MODE) == SPI_DATADIRECTION_2LINES_RXONLY) || \ ((MODE) == SPI_DATADIRECTION_1LINE_RX) || \ ((MODE) == SPI_DATADIRECTION_1LINE_TX)) /** * @brief Macro used by the assert_param function in order to check the mode * half duplex data direction values */ #define IS_SPI_DIRECTION_OK(DIRECTION) (((DIRECTION) == SPI_DIRECTION_RX) || \ ((DIRECTION) == SPI_DIRECTION_TX)) /** * @brief Macro used by the assert_param function in order to check the NSS * management values */ #define IS_SPI_SLAVEMANAGEMENT_OK(NSS) (((NSS) == SPI_NSS_SOFT) || \ ((NSS) == SPI_NSS_HARD)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the CRC polynomial */ #define IS_SPI_CRC_POLYNOMIAL_OK(POLYNOMIAL) ((POLYNOMIAL) > (uint8_t)0x00) /** * @brief Macro used by the assert_param function in order to check the SPI Mode values */ #define IS_SPI_MODE_OK(MODE) (((MODE) == SPI_MODE_MASTER) || \ ((MODE) == SPI_MODE_SLAVE)) /** * @brief Macro used by the assert_param function in order to check the baudrate values */ #define IS_SPI_BAUDRATE_PRESCALER_OK(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \ ((PRESCALER) == SPI_BAUDRATEPRESCALER_256)) /** * @brief Macro used by the assert_param function in order to check the polarity values */ #define IS_SPI_POLARITY_OK(CLKPOL) (((CLKPOL) == SPI_CLOCKPOLARITY_LOW) || \ ((CLKPOL) == SPI_CLOCKPOLARITY_HIGH)) /** * @brief Macro used by the assert_param function in order to check the phase values */ #define IS_SPI_PHASE_OK(CLKPHA) (((CLKPHA) == SPI_CLOCKPHASE_1EDGE) || \ ((CLKPHA) == SPI_CLOCKPHASE_2EDGE)) /** * @brief Macro used by the assert_param function in order to check the first * bit to be transmited values */ #define IS_SPI_FIRSTBIT_OK(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \ ((BIT) == SPI_FIRSTBIT_LSB)) /** * @brief Macro used by the assert_param function in order to check the CRC * Transmit/Receive */ #define IS_SPI_CRC_OK(CRC) (((CRC) == SPI_CRC_TX) || \ ((CRC) == SPI_CRC_RX)) /** * @brief Macro used by the assert_param function in order to check the * different flags values */ #define IS_SPI_FLAGS_OK(FLAG) (((FLAG) == SPI_FLAG_OVR) || \ ((FLAG) == SPI_FLAG_MODF) || \ ((FLAG) == SPI_FLAG_CRCERR) || \ ((FLAG) == SPI_FLAG_WKUP) || \ ((FLAG) == SPI_FLAG_TXE) || \ ((FLAG) == SPI_FLAG_RXNE) || \ ((FLAG) == SPI_FLAG_BSY)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the flag that can be cleared * by writing 0 */ #define IS_SPI_CLEAR_FLAGS_OK(FLAG) (((FLAG) == SPI_FLAG_CRCERR) || \ ((FLAG) == SPI_FLAG_WKUP)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the Interrupts */ #define IS_SPI_CONFIG_IT_OK(Interrupt) (((Interrupt) == SPI_IT_TXE) || \ ((Interrupt) == SPI_IT_RXNE) || \ ((Interrupt) == SPI_IT_ERR) || \ ((Interrupt) == SPI_IT_WKUP)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the pending bit */ #define IS_SPI_GET_IT_OK(ITPendingBit) (((ITPendingBit) == SPI_IT_OVR) || \ ((ITPendingBit) == SPI_IT_MODF) || \ ((ITPendingBit) == SPI_IT_CRCERR) || \ ((ITPendingBit) == SPI_IT_WKUP) || \ ((ITPendingBit) == SPI_IT_TXE) || \ ((ITPendingBit) == SPI_IT_RXNE)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the pending bit that can be cleared * by writing 0 */ #define IS_SPI_CLEAR_IT_OK(ITPendingBit) (((ITPendingBit) == SPI_IT_CRCERR) || \ ((ITPendingBit) == SPI_IT_WKUP)) /** * @} */ /** @addtogroup SPI_Exported_Functions * @{ */ void SPI_DeInit(void); void SPI_Init(SPI_FirstBit_TypeDef FirstBit, SPI_BaudRatePrescaler_TypeDef BaudRatePrescaler, SPI_Mode_TypeDef Mode, SPI_ClockPolarity_TypeDef ClockPolarity, SPI_ClockPhase_TypeDef ClockPhase, SPI_DataDirection_TypeDef Data_Direction, SPI_NSS_TypeDef Slave_Management, uint8_t CRCPolynomial); void SPI_Cmd(FunctionalState NewState); void SPI_ITConfig(SPI_IT_TypeDef SPI_IT, FunctionalState NewState); void SPI_SendData(uint8_t Data); uint8_t SPI_ReceiveData(void); void SPI_NSSInternalSoftwareCmd(FunctionalState NewState); void SPI_TransmitCRC(void); void SPI_CalculateCRCCmd(FunctionalState NewState); uint8_t SPI_GetCRC(SPI_CRC_TypeDef SPI_CRC); void SPI_ResetCRC(void); uint8_t SPI_GetCRCPolynomial(void); void SPI_BiDirectionalLineConfig(SPI_Direction_TypeDef SPI_Direction); FlagStatus SPI_GetFlagStatus(SPI_Flag_TypeDef SPI_FLAG); void SPI_ClearFlag(SPI_Flag_TypeDef SPI_FLAG); ITStatus SPI_GetITStatus(SPI_IT_TypeDef SPI_IT); void SPI_ClearITPendingBit(SPI_IT_TypeDef SPI_IT); /** * @} */ #endif /* __STM8S_SPI_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim1.h ================================================ /** ****************************************************************************** * @file stm8s_tim1.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM1 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM1_H #define __STM8S_TIM1_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /** @addtogroup TIM1_Exported_Types * @{ */ /** TIM1 Output Compare and PWM modes */ typedef enum { TIM1_OCMODE_TIMING = ((uint8_t)0x00), TIM1_OCMODE_ACTIVE = ((uint8_t)0x10), TIM1_OCMODE_INACTIVE = ((uint8_t)0x20), TIM1_OCMODE_TOGGLE = ((uint8_t)0x30), TIM1_OCMODE_PWM1 = ((uint8_t)0x60), TIM1_OCMODE_PWM2 = ((uint8_t)0x70) }TIM1_OCMode_TypeDef; #define IS_TIM1_OC_MODE_OK(MODE) (((MODE) == TIM1_OCMODE_TIMING) || \ ((MODE) == TIM1_OCMODE_ACTIVE) || \ ((MODE) == TIM1_OCMODE_INACTIVE) || \ ((MODE) == TIM1_OCMODE_TOGGLE)|| \ ((MODE) == TIM1_OCMODE_PWM1) || \ ((MODE) == TIM1_OCMODE_PWM2)) #define IS_TIM1_OCM_OK(MODE)(((MODE) == TIM1_OCMODE_TIMING) || \ ((MODE) == TIM1_OCMODE_ACTIVE) || \ ((MODE) == TIM1_OCMODE_INACTIVE) || \ ((MODE) == TIM1_OCMODE_TOGGLE)|| \ ((MODE) == TIM1_OCMODE_PWM1) || \ ((MODE) == TIM1_OCMODE_PWM2) || \ ((MODE) == (uint8_t)TIM1_FORCEDACTION_ACTIVE) || \ ((MODE) == (uint8_t)TIM1_FORCEDACTION_INACTIVE)) /** TIM1 One Pulse Mode */ typedef enum { TIM1_OPMODE_SINGLE = ((uint8_t)0x01), TIM1_OPMODE_REPETITIVE = ((uint8_t)0x00) }TIM1_OPMode_TypeDef; #define IS_TIM1_OPM_MODE_OK(MODE) (((MODE) == TIM1_OPMODE_SINGLE) || \ ((MODE) == TIM1_OPMODE_REPETITIVE)) /** TIM1 Channel */ typedef enum { TIM1_CHANNEL_1 = ((uint8_t)0x00), TIM1_CHANNEL_2 = ((uint8_t)0x01), TIM1_CHANNEL_3 = ((uint8_t)0x02), TIM1_CHANNEL_4 = ((uint8_t)0x03) }TIM1_Channel_TypeDef; #define IS_TIM1_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \ ((CHANNEL) == TIM1_CHANNEL_2) || \ ((CHANNEL) == TIM1_CHANNEL_3) || \ ((CHANNEL) == TIM1_CHANNEL_4)) #define IS_TIM1_PWMI_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \ ((CHANNEL) == TIM1_CHANNEL_2)) #define IS_TIM1_COMPLEMENTARY_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM1_CHANNEL_1) || \ ((CHANNEL) == TIM1_CHANNEL_2) || \ ((CHANNEL) == TIM1_CHANNEL_3)) /** TIM1 Counter Mode */ typedef enum { TIM1_COUNTERMODE_UP = ((uint8_t)0x00), TIM1_COUNTERMODE_DOWN = ((uint8_t)0x10), TIM1_COUNTERMODE_CENTERALIGNED1 = ((uint8_t)0x20), TIM1_COUNTERMODE_CENTERALIGNED2 = ((uint8_t)0x40), TIM1_COUNTERMODE_CENTERALIGNED3 = ((uint8_t)0x60) }TIM1_CounterMode_TypeDef; #define IS_TIM1_COUNTER_MODE_OK(MODE) (((MODE) == TIM1_COUNTERMODE_UP) || \ ((MODE) == TIM1_COUNTERMODE_DOWN) || \ ((MODE) == TIM1_COUNTERMODE_CENTERALIGNED1) || \ ((MODE) == TIM1_COUNTERMODE_CENTERALIGNED2) || \ ((MODE) == TIM1_COUNTERMODE_CENTERALIGNED3)) /** TIM1 Output Compare Polarity */ typedef enum { TIM1_OCPOLARITY_HIGH = ((uint8_t)0x00), TIM1_OCPOLARITY_LOW = ((uint8_t)0x22) }TIM1_OCPolarity_TypeDef; #define IS_TIM1_OC_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_OCPOLARITY_HIGH) || \ ((POLARITY) == TIM1_OCPOLARITY_LOW)) /** TIM1 Output Compare N Polarity */ typedef enum { TIM1_OCNPOLARITY_HIGH = ((uint8_t)0x00), TIM1_OCNPOLARITY_LOW = ((uint8_t)0x88) }TIM1_OCNPolarity_TypeDef; #define IS_TIM1_OCN_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_OCNPOLARITY_HIGH) || \ ((POLARITY) == TIM1_OCNPOLARITY_LOW)) /** TIM1 Output Compare states */ typedef enum { TIM1_OUTPUTSTATE_DISABLE = ((uint8_t)0x00), TIM1_OUTPUTSTATE_ENABLE = ((uint8_t)0x11) }TIM1_OutputState_TypeDef; #define IS_TIM1_OUTPUT_STATE_OK(STATE) (((STATE) == TIM1_OUTPUTSTATE_DISABLE) || \ ((STATE) == TIM1_OUTPUTSTATE_ENABLE)) /** TIM1 Output Compare N States */ typedef enum { TIM1_OUTPUTNSTATE_DISABLE = ((uint8_t)0x00), TIM1_OUTPUTNSTATE_ENABLE = ((uint8_t)0x44) } TIM1_OutputNState_TypeDef; #define IS_TIM1_OUTPUTN_STATE_OK(STATE) (((STATE) == TIM1_OUTPUTNSTATE_DISABLE) ||\ ((STATE) == TIM1_OUTPUTNSTATE_ENABLE)) /** TIM1 Break Input enable/disable */ typedef enum { TIM1_BREAK_ENABLE = ((uint8_t)0x10), TIM1_BREAK_DISABLE = ((uint8_t)0x00) }TIM1_BreakState_TypeDef; #define IS_TIM1_BREAK_STATE_OK(STATE) (((STATE) == TIM1_BREAK_ENABLE) || \ ((STATE) == TIM1_BREAK_DISABLE)) /** TIM1 Break Polarity */ typedef enum { TIM1_BREAKPOLARITY_LOW = ((uint8_t)0x00), TIM1_BREAKPOLARITY_HIGH = ((uint8_t)0x20) }TIM1_BreakPolarity_TypeDef; #define IS_TIM1_BREAK_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_BREAKPOLARITY_LOW) || \ ((POLARITY) == TIM1_BREAKPOLARITY_HIGH)) /** TIM1 AOE Bit Set/Reset */ typedef enum { TIM1_AUTOMATICOUTPUT_ENABLE = ((uint8_t)0x40), TIM1_AUTOMATICOUTPUT_DISABLE = ((uint8_t)0x00) }TIM1_AutomaticOutput_TypeDef; #define IS_TIM1_AUTOMATIC_OUTPUT_STATE_OK(STATE) (((STATE) == TIM1_AUTOMATICOUTPUT_ENABLE) || \ ((STATE) == TIM1_AUTOMATICOUTPUT_DISABLE)) /** TIM1 Lock levels */ typedef enum { TIM1_LOCKLEVEL_OFF = ((uint8_t)0x00), TIM1_LOCKLEVEL_1 = ((uint8_t)0x01), TIM1_LOCKLEVEL_2 = ((uint8_t)0x02), TIM1_LOCKLEVEL_3 = ((uint8_t)0x03) }TIM1_LockLevel_TypeDef; #define IS_TIM1_LOCK_LEVEL_OK(LEVEL) (((LEVEL) == TIM1_LOCKLEVEL_OFF) || \ ((LEVEL) == TIM1_LOCKLEVEL_1) || \ ((LEVEL) == TIM1_LOCKLEVEL_2) || \ ((LEVEL) == TIM1_LOCKLEVEL_3)) /** TIM1 OSSI: Off-State Selection for Idle mode states */ typedef enum { TIM1_OSSISTATE_ENABLE = ((uint8_t)0x04), TIM1_OSSISTATE_DISABLE = ((uint8_t)0x00) }TIM1_OSSIState_TypeDef; #define IS_TIM1_OSSI_STATE_OK(STATE) (((STATE) == TIM1_OSSISTATE_ENABLE) || \ ((STATE) == TIM1_OSSISTATE_DISABLE)) /** TIM1 Output Compare Idle State */ typedef enum { TIM1_OCIDLESTATE_SET = ((uint8_t)0x55), TIM1_OCIDLESTATE_RESET = ((uint8_t)0x00) }TIM1_OCIdleState_TypeDef; #define IS_TIM1_OCIDLE_STATE_OK(STATE) (((STATE) == TIM1_OCIDLESTATE_SET) || \ ((STATE) == TIM1_OCIDLESTATE_RESET)) /** TIM1 Output Compare N Idle State */ typedef enum { TIM1_OCNIDLESTATE_SET = ((uint8_t)0x2A), TIM1_OCNIDLESTATE_RESET = ((uint8_t)0x00) }TIM1_OCNIdleState_TypeDef; #define IS_TIM1_OCNIDLE_STATE_OK(STATE) (((STATE) == TIM1_OCNIDLESTATE_SET) || \ ((STATE) == TIM1_OCNIDLESTATE_RESET)) /** TIM1 Input Capture Polarity */ typedef enum { TIM1_ICPOLARITY_RISING = ((uint8_t)0x00), TIM1_ICPOLARITY_FALLING = ((uint8_t)0x01) }TIM1_ICPolarity_TypeDef; #define IS_TIM1_IC_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_ICPOLARITY_RISING) || \ ((POLARITY) == TIM1_ICPOLARITY_FALLING)) /** TIM1 Input Capture Selection */ typedef enum { TIM1_ICSELECTION_DIRECTTI = ((uint8_t)0x01), TIM1_ICSELECTION_INDIRECTTI = ((uint8_t)0x02), TIM1_ICSELECTION_TRGI = ((uint8_t)0x03) }TIM1_ICSelection_TypeDef; #define IS_TIM1_IC_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM1_ICSELECTION_INDIRECTTI) || \ ((SELECTION) == TIM1_ICSELECTION_TRGI)) /** TIM1 Input Capture Prescaler */ typedef enum { TIM1_ICPSC_DIV1 = ((uint8_t)0x00), TIM1_ICPSC_DIV2 = ((uint8_t)0x04), TIM1_ICPSC_DIV4 = ((uint8_t)0x08), TIM1_ICPSC_DIV8 = ((uint8_t)0x0C) }TIM1_ICPSC_TypeDef; #define IS_TIM1_IC_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM1_ICPSC_DIV1) || \ ((PRESCALER) == TIM1_ICPSC_DIV2) || \ ((PRESCALER) == TIM1_ICPSC_DIV4) || \ ((PRESCALER) == TIM1_ICPSC_DIV8)) /** TIM1 Input Capture Filer Value */ #define IS_TIM1_IC_FILTER_OK(ICFILTER) ((ICFILTER) <= 0x0F) /** TIM1 External Trigger Filer Value */ #define IS_TIM1_EXT_TRG_FILTER_OK(FILTER) ((FILTER) <= 0x0F) /** TIM1 interrupt sources */ typedef enum { TIM1_IT_UPDATE = ((uint8_t)0x01), TIM1_IT_CC1 = ((uint8_t)0x02), TIM1_IT_CC2 = ((uint8_t)0x04), TIM1_IT_CC3 = ((uint8_t)0x08), TIM1_IT_CC4 = ((uint8_t)0x10), TIM1_IT_COM = ((uint8_t)0x20), TIM1_IT_TRIGGER = ((uint8_t)0x40), TIM1_IT_BREAK = ((uint8_t)0x80) }TIM1_IT_TypeDef; #define IS_TIM1_IT_OK(IT) ((IT) != 0x00) #define IS_TIM1_GET_IT_OK(IT) (((IT) == TIM1_IT_UPDATE) || \ ((IT) == TIM1_IT_CC1) || \ ((IT) == TIM1_IT_CC2) || \ ((IT) == TIM1_IT_CC3) || \ ((IT) == TIM1_IT_CC4) || \ ((IT) == TIM1_IT_COM) || \ ((IT) == TIM1_IT_TRIGGER) || \ ((IT) == TIM1_IT_BREAK)) /** TIM1 External Trigger Prescaler */ typedef enum { TIM1_EXTTRGPSC_OFF = ((uint8_t)0x00), TIM1_EXTTRGPSC_DIV2 = ((uint8_t)0x10), TIM1_EXTTRGPSC_DIV4 = ((uint8_t)0x20), TIM1_EXTTRGPSC_DIV8 = ((uint8_t)0x30) }TIM1_ExtTRGPSC_TypeDef; #define IS_TIM1_EXT_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM1_EXTTRGPSC_OFF) || \ ((PRESCALER) == TIM1_EXTTRGPSC_DIV2) || \ ((PRESCALER) == TIM1_EXTTRGPSC_DIV4) || \ ((PRESCALER) == TIM1_EXTTRGPSC_DIV8)) /** TIM1 Internal Trigger Selection */ typedef enum { TIM1_TS_TIM6 = ((uint8_t)0x00), /*!< TRIG Input source = TIM6 TRIG Output */ TIM1_TS_TIM5 = ((uint8_t)0x30), /*!< TRIG Input source = TIM5 TRIG Output */ TIM1_TS_TI1F_ED = ((uint8_t)0x40), TIM1_TS_TI1FP1 = ((uint8_t)0x50), TIM1_TS_TI2FP2 = ((uint8_t)0x60), TIM1_TS_ETRF = ((uint8_t)0x70) }TIM1_TS_TypeDef; #define IS_TIM1_TRIGGER_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_TS_TI1F_ED) || \ ((SELECTION) == TIM1_TS_TI1FP1) || \ ((SELECTION) == TIM1_TS_TI2FP2) || \ ((SELECTION) == TIM1_TS_ETRF) || \ ((SELECTION) == TIM1_TS_TIM5) || \ ((SELECTION) == TIM1_TS_TIM6)) #define IS_TIM1_TIX_TRIGGER_SELECTION_OK(SELECTION) (((SELECTION) == TIM1_TS_TI1F_ED) || \ ((SELECTION) == TIM1_TS_TI1FP1) || \ ((SELECTION) == TIM1_TS_TI2FP2)) /** TIM1 TIx External Clock Source */ typedef enum { TIM1_TIXEXTERNALCLK1SOURCE_TI1ED = ((uint8_t)0x40), TIM1_TIXEXTERNALCLK1SOURCE_TI1 = ((uint8_t)0x50), TIM1_TIXEXTERNALCLK1SOURCE_TI2 = ((uint8_t)0x60) }TIM1_TIxExternalCLK1Source_TypeDef; #define IS_TIM1_TIXCLK_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI1ED) || \ ((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI2) || \ ((SOURCE) == TIM1_TIXEXTERNALCLK1SOURCE_TI1)) /** TIM1 External Trigger Polarity */ typedef enum { TIM1_EXTTRGPOLARITY_INVERTED = ((uint8_t)0x80), TIM1_EXTTRGPOLARITY_NONINVERTED = ((uint8_t)0x00) }TIM1_ExtTRGPolarity_TypeDef; #define IS_TIM1_EXT_POLARITY_OK(POLARITY) (((POLARITY) == TIM1_EXTTRGPOLARITY_INVERTED) || \ ((POLARITY) == TIM1_EXTTRGPOLARITY_NONINVERTED)) /** TIM1 Prescaler Reload Mode */ typedef enum { TIM1_PSCRELOADMODE_UPDATE = ((uint8_t)0x00), TIM1_PSCRELOADMODE_IMMEDIATE = ((uint8_t)0x01) }TIM1_PSCReloadMode_TypeDef; #define IS_TIM1_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM1_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM1_PSCRELOADMODE_IMMEDIATE)) /** TIM1 Encoder Mode */ typedef enum { TIM1_ENCODERMODE_TI1 = ((uint8_t)0x01), TIM1_ENCODERMODE_TI2 = ((uint8_t)0x02), TIM1_ENCODERMODE_TI12 = ((uint8_t)0x03) }TIM1_EncoderMode_TypeDef; #define IS_TIM1_ENCODER_MODE_OK(MODE) (((MODE) == TIM1_ENCODERMODE_TI1) || \ ((MODE) == TIM1_ENCODERMODE_TI2) || \ ((MODE) == TIM1_ENCODERMODE_TI12)) /** TIM1 Event Source */ typedef enum { TIM1_EVENTSOURCE_UPDATE = ((uint8_t)0x01), TIM1_EVENTSOURCE_CC1 = ((uint8_t)0x02), TIM1_EVENTSOURCE_CC2 = ((uint8_t)0x04), TIM1_EVENTSOURCE_CC3 = ((uint8_t)0x08), TIM1_EVENTSOURCE_CC4 = ((uint8_t)0x10), TIM1_EVENTSOURCE_COM = ((uint8_t)0x20), TIM1_EVENTSOURCE_TRIGGER = ((uint8_t)0x40), TIM1_EVENTSOURCE_BREAK = ((uint8_t)0x80) }TIM1_EventSource_TypeDef; #define IS_TIM1_EVENT_SOURCE_OK(SOURCE) ((SOURCE) != 0x00) /** TIM1 Update Source */ typedef enum { TIM1_UPDATESOURCE_GLOBAL = ((uint8_t)0x00), TIM1_UPDATESOURCE_REGULAR = ((uint8_t)0x01) }TIM1_UpdateSource_TypeDef; #define IS_TIM1_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM1_UPDATESOURCE_REGULAR)) /** TIM1 Trigger Output Source */ typedef enum { TIM1_TRGOSOURCE_RESET = ((uint8_t)0x00), TIM1_TRGOSOURCE_ENABLE = ((uint8_t)0x10), TIM1_TRGOSOURCE_UPDATE = ((uint8_t)0x20), TIM1_TRGOSource_OC1 = ((uint8_t)0x30), TIM1_TRGOSOURCE_OC1REF = ((uint8_t)0x40), TIM1_TRGOSOURCE_OC2REF = ((uint8_t)0x50), TIM1_TRGOSOURCE_OC3REF = ((uint8_t)0x60) }TIM1_TRGOSource_TypeDef; #define IS_TIM1_TRGO_SOURCE_OK(SOURCE) (((SOURCE) == TIM1_TRGOSOURCE_RESET) || \ ((SOURCE) == TIM1_TRGOSOURCE_ENABLE) || \ ((SOURCE) == TIM1_TRGOSOURCE_UPDATE) || \ ((SOURCE) == TIM1_TRGOSource_OC1) || \ ((SOURCE) == TIM1_TRGOSOURCE_OC1REF) || \ ((SOURCE) == TIM1_TRGOSOURCE_OC2REF) || \ ((SOURCE) == TIM1_TRGOSOURCE_OC3REF)) /** TIM1 Slave Mode */ typedef enum { TIM1_SLAVEMODE_RESET = ((uint8_t)0x04), TIM1_SLAVEMODE_GATED = ((uint8_t)0x05), TIM1_SLAVEMODE_TRIGGER = ((uint8_t)0x06), TIM1_SLAVEMODE_EXTERNAL1 = ((uint8_t)0x07) }TIM1_SlaveMode_TypeDef; #define IS_TIM1_SLAVE_MODE_OK(MODE) (((MODE) == TIM1_SLAVEMODE_RESET) || \ ((MODE) == TIM1_SLAVEMODE_GATED) || \ ((MODE) == TIM1_SLAVEMODE_TRIGGER) || \ ((MODE) == TIM1_SLAVEMODE_EXTERNAL1)) /** TIM1 Flags */ typedef enum { TIM1_FLAG_UPDATE = ((uint16_t)0x0001), TIM1_FLAG_CC1 = ((uint16_t)0x0002), TIM1_FLAG_CC2 = ((uint16_t)0x0004), TIM1_FLAG_CC3 = ((uint16_t)0x0008), TIM1_FLAG_CC4 = ((uint16_t)0x0010), TIM1_FLAG_COM = ((uint16_t)0x0020), TIM1_FLAG_TRIGGER = ((uint16_t)0x0040), TIM1_FLAG_BREAK = ((uint16_t)0x0080), TIM1_FLAG_CC1OF = ((uint16_t)0x0200), TIM1_FLAG_CC2OF = ((uint16_t)0x0400), TIM1_FLAG_CC3OF = ((uint16_t)0x0800), TIM1_FLAG_CC4OF = ((uint16_t)0x1000) }TIM1_FLAG_TypeDef; #define IS_TIM1_GET_FLAG_OK(FLAG) (((FLAG) == TIM1_FLAG_UPDATE) || \ ((FLAG) == TIM1_FLAG_CC1) || \ ((FLAG) == TIM1_FLAG_CC2) || \ ((FLAG) == TIM1_FLAG_CC3) || \ ((FLAG) == TIM1_FLAG_CC4) || \ ((FLAG) == TIM1_FLAG_COM) || \ ((FLAG) == TIM1_FLAG_TRIGGER) || \ ((FLAG) == TIM1_FLAG_BREAK) || \ ((FLAG) == TIM1_FLAG_CC1OF) || \ ((FLAG) == TIM1_FLAG_CC2OF) || \ ((FLAG) == TIM1_FLAG_CC3OF) || \ ((FLAG) == TIM1_FLAG_CC4OF)) #define IS_TIM1_CLEAR_FLAG_OK(FLAG) ((((uint16_t)(FLAG) & (uint16_t)0xE100) == 0x0000) && ((FLAG) != 0x0000)) /** TIM1 Forced Action */ typedef enum { TIM1_FORCEDACTION_ACTIVE = ((uint8_t)0x50), TIM1_FORCEDACTION_INACTIVE = ((uint8_t)0x40) }TIM1_ForcedAction_TypeDef; #define IS_TIM1_FORCED_ACTION_OK(ACTION) (((ACTION) == TIM1_FORCEDACTION_ACTIVE) || \ ((ACTION) == TIM1_FORCEDACTION_INACTIVE)) /** * @} */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM1_Exported_Functions * @{ */ void TIM1_DeInit(void); void TIM1_TimeBaseInit(uint16_t TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, uint16_t TIM1_Period, uint8_t TIM1_RepetitionCounter); void TIM1_OC1Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); void TIM1_OC2Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); void TIM1_OC3Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); void TIM1_OC4Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState); void TIM1_BDTRConfig(TIM1_OSSIState_TypeDef TIM1_OSSIState, TIM1_LockLevel_TypeDef TIM1_LockLevel, uint8_t TIM1_DeadTime, TIM1_BreakState_TypeDef TIM1_Break, TIM1_BreakPolarity_TypeDef TIM1_BreakPolarity, TIM1_AutomaticOutput_TypeDef TIM1_AutomaticOutput); void TIM1_ICInit(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, uint8_t TIM1_ICFilter); void TIM1_PWMIConfig(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, uint8_t TIM1_ICFilter); void TIM1_Cmd(FunctionalState NewState); void TIM1_CtrlPWMOutputs(FunctionalState NewState); void TIM1_ITConfig(TIM1_IT_TypeDef TIM1_IT, FunctionalState NewState); void TIM1_InternalClockConfig(void); void TIM1_ETRClockMode1Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); void TIM1_ETRClockMode2Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); void TIM1_ETRConfig(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); void TIM1_TIxExternalClockConfig(TIM1_TIxExternalCLK1Source_TypeDef TIM1_TIxExternalCLKSource, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, uint8_t ICFilter); void TIM1_SelectInputTrigger(TIM1_TS_TypeDef TIM1_InputTriggerSource); void TIM1_UpdateDisableConfig(FunctionalState NewState); void TIM1_UpdateRequestConfig(TIM1_UpdateSource_TypeDef TIM1_UpdateSource); void TIM1_SelectHallSensor(FunctionalState NewState); void TIM1_SelectOnePulseMode(TIM1_OPMode_TypeDef TIM1_OPMode); void TIM1_SelectOutputTrigger(TIM1_TRGOSource_TypeDef TIM1_TRGOSource); void TIM1_SelectSlaveMode(TIM1_SlaveMode_TypeDef TIM1_SlaveMode); void TIM1_SelectMasterSlaveMode(FunctionalState NewState); void TIM1_EncoderInterfaceConfig(TIM1_EncoderMode_TypeDef TIM1_EncoderMode, TIM1_ICPolarity_TypeDef TIM1_IC1Polarity, TIM1_ICPolarity_TypeDef TIM1_IC2Polarity); void TIM1_PrescalerConfig(uint16_t Prescaler, TIM1_PSCReloadMode_TypeDef TIM1_PSCReloadMode); void TIM1_CounterModeConfig(TIM1_CounterMode_TypeDef TIM1_CounterMode); void TIM1_ForcedOC1Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); void TIM1_ForcedOC2Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); void TIM1_ForcedOC3Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); void TIM1_ForcedOC4Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); void TIM1_ARRPreloadConfig(FunctionalState NewState); void TIM1_SelectCOM(FunctionalState NewState); void TIM1_CCPreloadControl(FunctionalState NewState); void TIM1_OC1PreloadConfig(FunctionalState NewState); void TIM1_OC2PreloadConfig(FunctionalState NewState); void TIM1_OC3PreloadConfig(FunctionalState NewState); void TIM1_OC4PreloadConfig(FunctionalState NewState); void TIM1_OC1FastConfig(FunctionalState NewState); void TIM1_OC2FastConfig(FunctionalState NewState); void TIM1_OC3FastConfig(FunctionalState NewState); void TIM1_OC4FastConfig(FunctionalState NewState); void TIM1_GenerateEvent(TIM1_EventSource_TypeDef TIM1_EventSource); void TIM1_OC1PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); void TIM1_OC1NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); void TIM1_OC2PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); void TIM1_OC2NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); void TIM1_OC3PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); void TIM1_OC3NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); void TIM1_OC4PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); void TIM1_CCxCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState NewState); void TIM1_CCxNCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState NewState); void TIM1_SelectOCxM(TIM1_Channel_TypeDef TIM1_Channel, TIM1_OCMode_TypeDef TIM1_OCMode); void TIM1_SetCounter(uint16_t Counter); void TIM1_SetAutoreload(uint16_t Autoreload); void TIM1_SetCompare1(uint16_t Compare1); void TIM1_SetCompare2(uint16_t Compare2); void TIM1_SetCompare3(uint16_t Compare3); void TIM1_SetCompare4(uint16_t Compare4); void TIM1_SetIC1Prescaler(TIM1_ICPSC_TypeDef TIM1_IC1Prescaler); void TIM1_SetIC2Prescaler(TIM1_ICPSC_TypeDef TIM1_IC2Prescaler); void TIM1_SetIC3Prescaler(TIM1_ICPSC_TypeDef TIM1_IC3Prescaler); void TIM1_SetIC4Prescaler(TIM1_ICPSC_TypeDef TIM1_IC4Prescaler); uint16_t TIM1_GetCapture1(void); uint16_t TIM1_GetCapture2(void); uint16_t TIM1_GetCapture3(void); uint16_t TIM1_GetCapture4(void); uint16_t TIM1_GetCounter(void); uint16_t TIM1_GetPrescaler(void); FlagStatus TIM1_GetFlagStatus(TIM1_FLAG_TypeDef TIM1_FLAG); void TIM1_ClearFlag(TIM1_FLAG_TypeDef TIM1_FLAG); ITStatus TIM1_GetITStatus(TIM1_IT_TypeDef TIM1_IT); void TIM1_ClearITPendingBit(TIM1_IT_TypeDef TIM1_IT); /** * @} */ #endif /* __STM8S_TIM1_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim2.h ================================================ /** ****************************************************************************** * @file stm8s_tim2.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM2 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM2_H #define __STM8S_TIM2_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** TIM2 Forced Action */ typedef enum { TIM2_FORCEDACTION_ACTIVE = ((uint8_t)0x50), TIM2_FORCEDACTION_INACTIVE = ((uint8_t)0x40) }TIM2_ForcedAction_TypeDef; #define IS_TIM2_FORCED_ACTION_OK(ACTION) (((ACTION) == TIM2_FORCEDACTION_ACTIVE) || \ ((ACTION) == TIM2_FORCEDACTION_INACTIVE)) /** TIM2 Prescaler */ typedef enum { TIM2_PRESCALER_1 = ((uint8_t)0x00), TIM2_PRESCALER_2 = ((uint8_t)0x01), TIM2_PRESCALER_4 = ((uint8_t)0x02), TIM2_PRESCALER_8 = ((uint8_t)0x03), TIM2_PRESCALER_16 = ((uint8_t)0x04), TIM2_PRESCALER_32 = ((uint8_t)0x05), TIM2_PRESCALER_64 = ((uint8_t)0x06), TIM2_PRESCALER_128 = ((uint8_t)0x07), TIM2_PRESCALER_256 = ((uint8_t)0x08), TIM2_PRESCALER_512 = ((uint8_t)0x09), TIM2_PRESCALER_1024 = ((uint8_t)0x0A), TIM2_PRESCALER_2048 = ((uint8_t)0x0B), TIM2_PRESCALER_4096 = ((uint8_t)0x0C), TIM2_PRESCALER_8192 = ((uint8_t)0x0D), TIM2_PRESCALER_16384 = ((uint8_t)0x0E), TIM2_PRESCALER_32768 = ((uint8_t)0x0F) }TIM2_Prescaler_TypeDef; #define IS_TIM2_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM2_PRESCALER_1 ) || \ ((PRESCALER) == TIM2_PRESCALER_2 ) || \ ((PRESCALER) == TIM2_PRESCALER_4 ) || \ ((PRESCALER) == TIM2_PRESCALER_8 ) || \ ((PRESCALER) == TIM2_PRESCALER_16 ) || \ ((PRESCALER) == TIM2_PRESCALER_32 ) || \ ((PRESCALER) == TIM2_PRESCALER_64 ) || \ ((PRESCALER) == TIM2_PRESCALER_128 ) || \ ((PRESCALER) == TIM2_PRESCALER_256 ) || \ ((PRESCALER) == TIM2_PRESCALER_512 ) || \ ((PRESCALER) == TIM2_PRESCALER_1024 ) || \ ((PRESCALER) == TIM2_PRESCALER_2048 ) || \ ((PRESCALER) == TIM2_PRESCALER_4096 ) || \ ((PRESCALER) == TIM2_PRESCALER_8192 ) || \ ((PRESCALER) == TIM2_PRESCALER_16384 ) || \ ((PRESCALER) == TIM2_PRESCALER_32768 )) /** TIM2 Output Compare and PWM modes */ typedef enum { TIM2_OCMODE_TIMING = ((uint8_t)0x00), TIM2_OCMODE_ACTIVE = ((uint8_t)0x10), TIM2_OCMODE_INACTIVE = ((uint8_t)0x20), TIM2_OCMODE_TOGGLE = ((uint8_t)0x30), TIM2_OCMODE_PWM1 = ((uint8_t)0x60), TIM2_OCMODE_PWM2 = ((uint8_t)0x70) }TIM2_OCMode_TypeDef; #define IS_TIM2_OC_MODE_OK(MODE) (((MODE) == TIM2_OCMODE_TIMING) || \ ((MODE) == TIM2_OCMODE_ACTIVE) || \ ((MODE) == TIM2_OCMODE_INACTIVE) || \ ((MODE) == TIM2_OCMODE_TOGGLE)|| \ ((MODE) == TIM2_OCMODE_PWM1) || \ ((MODE) == TIM2_OCMODE_PWM2)) #define IS_TIM2_OCM_OK(MODE)(((MODE) == TIM2_OCMODE_TIMING) || \ ((MODE) == TIM2_OCMODE_ACTIVE) || \ ((MODE) == TIM2_OCMODE_INACTIVE) || \ ((MODE) == TIM2_OCMODE_TOGGLE)|| \ ((MODE) == TIM2_OCMODE_PWM1) || \ ((MODE) == TIM2_OCMODE_PWM2) || \ ((MODE) == (uint8_t)TIM2_FORCEDACTION_ACTIVE) || \ ((MODE) == (uint8_t)TIM2_FORCEDACTION_INACTIVE)) /** TIM2 One Pulse Mode */ typedef enum { TIM2_OPMODE_SINGLE = ((uint8_t)0x01), TIM2_OPMODE_REPETITIVE = ((uint8_t)0x00) }TIM2_OPMode_TypeDef; #define IS_TIM2_OPM_MODE_OK(MODE) (((MODE) == TIM2_OPMODE_SINGLE) || \ ((MODE) == TIM2_OPMODE_REPETITIVE)) /** TIM2 Channel */ typedef enum { TIM2_CHANNEL_1 = ((uint8_t)0x00), TIM2_CHANNEL_2 = ((uint8_t)0x01), TIM2_CHANNEL_3 = ((uint8_t)0x02) }TIM2_Channel_TypeDef; #define IS_TIM2_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM2_CHANNEL_1) || \ ((CHANNEL) == TIM2_CHANNEL_2) || \ ((CHANNEL) == TIM2_CHANNEL_3)) #define IS_TIM2_PWMI_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM2_CHANNEL_1) || \ ((CHANNEL) == TIM2_CHANNEL_2)) /** TIM2 Output Compare Polarity */ typedef enum { TIM2_OCPOLARITY_HIGH = ((uint8_t)0x00), TIM2_OCPOLARITY_LOW = ((uint8_t)0x22) }TIM2_OCPolarity_TypeDef; #define IS_TIM2_OC_POLARITY_OK(POLARITY) (((POLARITY) == TIM2_OCPOLARITY_HIGH) || \ ((POLARITY) == TIM2_OCPOLARITY_LOW)) /** TIM2 Output Compare states */ typedef enum { TIM2_OUTPUTSTATE_DISABLE = ((uint8_t)0x00), TIM2_OUTPUTSTATE_ENABLE = ((uint8_t)0x11) }TIM2_OutputState_TypeDef; #define IS_TIM2_OUTPUT_STATE_OK(STATE) (((STATE) == TIM2_OUTPUTSTATE_DISABLE) || \ ((STATE) == TIM2_OUTPUTSTATE_ENABLE)) /** TIM2 Input Capture Polarity */ typedef enum { TIM2_ICPOLARITY_RISING = ((uint8_t)0x00), TIM2_ICPOLARITY_FALLING = ((uint8_t)0x44) }TIM2_ICPolarity_TypeDef; #define IS_TIM2_IC_POLARITY_OK(POLARITY) (((POLARITY) == TIM2_ICPOLARITY_RISING) || \ ((POLARITY) == TIM2_ICPOLARITY_FALLING)) /** TIM2 Input Capture Selection */ typedef enum { TIM2_ICSELECTION_DIRECTTI = ((uint8_t)0x01), TIM2_ICSELECTION_INDIRECTTI = ((uint8_t)0x02), TIM2_ICSELECTION_TRGI = ((uint8_t)0x03) }TIM2_ICSelection_TypeDef; #define IS_TIM2_IC_SELECTION_OK(SELECTION) (((SELECTION) == TIM2_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM2_ICSELECTION_INDIRECTTI) || \ ((SELECTION) == TIM2_ICSELECTION_TRGI)) #define IS_TIM2_IC_SELECTION1_OK(SELECTION) (((SELECTION) == TIM2_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM2_ICSELECTION_TRGI)) /** TIM2 Input Capture Prescaler */ typedef enum { TIM2_ICPSC_DIV1 = ((uint8_t)0x00), TIM2_ICPSC_DIV2 = ((uint8_t)0x04), TIM2_ICPSC_DIV4 = ((uint8_t)0x08), TIM2_ICPSC_DIV8 = ((uint8_t)0x0C) }TIM2_ICPSC_TypeDef; #define IS_TIM2_IC_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM2_ICPSC_DIV1) || \ ((PRESCALER) == TIM2_ICPSC_DIV2) || \ ((PRESCALER) == TIM2_ICPSC_DIV4) || \ ((PRESCALER) == TIM2_ICPSC_DIV8)) /** TIM2 Input Capture Filer Value */ #define IS_TIM2_IC_FILTER_OK(ICFILTER) ((ICFILTER) <= 0x0F) /** TIM2 interrupt sources */ typedef enum { TIM2_IT_UPDATE = ((uint8_t)0x01), TIM2_IT_CC1 = ((uint8_t)0x02), TIM2_IT_CC2 = ((uint8_t)0x04), TIM2_IT_CC3 = ((uint8_t)0x08) }TIM2_IT_TypeDef; #define IS_TIM2_IT_OK(IT) (((IT) != 0x00) && ((IT) <= 0x0F)) #define IS_TIM2_GET_IT_OK(IT) (((IT) == TIM2_IT_UPDATE) || \ ((IT) == TIM2_IT_CC1) || \ ((IT) == TIM2_IT_CC2) || \ ((IT) == TIM2_IT_CC3)) /** TIM2 Prescaler Reload Mode */ typedef enum { TIM2_PSCRELOADMODE_UPDATE = ((uint8_t)0x00), TIM2_PSCRELOADMODE_IMMEDIATE = ((uint8_t)0x01) }TIM2_PSCReloadMode_TypeDef; #define IS_TIM2_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM2_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM2_PSCRELOADMODE_IMMEDIATE)) /** TIM2 Event Source */ typedef enum { TIM2_EVENTSOURCE_UPDATE = ((uint8_t)0x01), TIM2_EVENTSOURCE_CC1 = ((uint8_t)0x02), TIM2_EVENTSOURCE_CC2 = ((uint8_t)0x04), TIM2_EVENTSOURCE_CC3 = ((uint8_t)0x08) }TIM2_EventSource_TypeDef; #define IS_TIM2_EVENT_SOURCE_OK(SOURCE) (((SOURCE) != 0x00)) /** TIM2 Update Source */ typedef enum { TIM2_UPDATESOURCE_GLOBAL = ((uint8_t)0x00), TIM2_UPDATESOURCE_REGULAR = ((uint8_t)0x01) }TIM2_UpdateSource_TypeDef; #define IS_TIM2_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM2_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM2_UPDATESOURCE_REGULAR)) /** TIM2 Flags */ typedef enum { TIM2_FLAG_UPDATE = ((uint16_t)0x0001), TIM2_FLAG_CC1 = ((uint16_t)0x0002), TIM2_FLAG_CC2 = ((uint16_t)0x0004), TIM2_FLAG_CC3 = ((uint16_t)0x0008), TIM2_FLAG_CC1OF = ((uint16_t)0x0200), TIM2_FLAG_CC2OF = ((uint16_t)0x0400), TIM2_FLAG_CC3OF = ((uint16_t)0x0800) }TIM2_FLAG_TypeDef; #define IS_TIM2_GET_FLAG_OK(FLAG) (((FLAG) == TIM2_FLAG_UPDATE) || \ ((FLAG) == TIM2_FLAG_CC1) || \ ((FLAG) == TIM2_FLAG_CC2) || \ ((FLAG) == TIM2_FLAG_CC3) || \ ((FLAG) == TIM2_FLAG_CC1OF) || \ ((FLAG) == TIM2_FLAG_CC2OF) || \ ((FLAG) == TIM2_FLAG_CC3OF)) #define IS_TIM2_CLEAR_FLAG_OK(FLAG) ((((uint16_t)(FLAG) & 0xF1F0) == 0x0000) && ((uint16_t)(FLAG) != 0x0000)) /** * @} */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM2_Exported_Functions * @{ */ void TIM2_DeInit(void); void TIM2_TimeBaseInit(TIM2_Prescaler_TypeDef TIM2_Prescaler, uint16_t TIM2_Period); void TIM2_OC1Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_OC2Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_OC3Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_ICInit(TIM2_Channel_TypeDef TIM2_Channel, TIM2_ICPolarity_TypeDef TIM2_ICPolarity, TIM2_ICSelection_TypeDef TIM2_ICSelection, TIM2_ICPSC_TypeDef TIM2_ICPrescaler, uint8_t TIM2_ICFilter); void TIM2_PWMIConfig(TIM2_Channel_TypeDef TIM2_Channel, TIM2_ICPolarity_TypeDef TIM2_ICPolarity, TIM2_ICSelection_TypeDef TIM2_ICSelection, TIM2_ICPSC_TypeDef TIM2_ICPrescaler, uint8_t TIM2_ICFilter); void TIM2_Cmd(FunctionalState NewState); void TIM2_ITConfig(TIM2_IT_TypeDef TIM2_IT, FunctionalState NewState); void TIM2_InternalClockConfig(void); void TIM2_UpdateDisableConfig(FunctionalState NewState); void TIM2_UpdateRequestConfig(TIM2_UpdateSource_TypeDef TIM2_UpdateSource); void TIM2_SelectOnePulseMode(TIM2_OPMode_TypeDef TIM2_OPMode); void TIM2_PrescalerConfig(TIM2_Prescaler_TypeDef Prescaler, TIM2_PSCReloadMode_TypeDef TIM2_PSCReloadMode); void TIM2_ForcedOC1Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); void TIM2_ForcedOC2Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); void TIM2_ForcedOC3Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); void TIM2_ARRPreloadConfig(FunctionalState NewState); void TIM2_CCPreloadControl(FunctionalState NewState); void TIM2_OC1PreloadConfig(FunctionalState NewState); void TIM2_OC2PreloadConfig(FunctionalState NewState); void TIM2_OC3PreloadConfig(FunctionalState NewState); void TIM2_GenerateEvent(TIM2_EventSource_TypeDef TIM2_EventSource); void TIM2_OC1PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_OC2PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_OC3PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); void TIM2_CCxCmd(TIM2_Channel_TypeDef TIM2_Channel, FunctionalState NewState); void TIM2_SelectOCxM(TIM2_Channel_TypeDef TIM2_Channel, TIM2_OCMode_TypeDef TIM2_OCMode); void TIM2_SetCounter(uint16_t Counter); void TIM2_SetAutoreload(uint16_t Autoreload); void TIM2_SetCompare1(uint16_t Compare1); void TIM2_SetCompare2(uint16_t Compare2); void TIM2_SetCompare3(uint16_t Compare3); void TIM2_SetIC1Prescaler(TIM2_ICPSC_TypeDef TIM2_IC1Prescaler); void TIM2_SetIC2Prescaler(TIM2_ICPSC_TypeDef TIM2_IC2Prescaler); void TIM2_SetIC3Prescaler(TIM2_ICPSC_TypeDef TIM2_IC3Prescaler); uint16_t TIM2_GetCapture1(void); uint16_t TIM2_GetCapture2(void); uint16_t TIM2_GetCapture3(void); uint16_t TIM2_GetCounter(void); TIM2_Prescaler_TypeDef TIM2_GetPrescaler(void); FlagStatus TIM2_GetFlagStatus(TIM2_FLAG_TypeDef TIM2_FLAG); void TIM2_ClearFlag(TIM2_FLAG_TypeDef TIM2_FLAG); ITStatus TIM2_GetITStatus(TIM2_IT_TypeDef TIM2_IT); void TIM2_ClearITPendingBit(TIM2_IT_TypeDef TIM2_IT); /** * @} */ #endif /* __STM8S_TIM2_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim3.h ================================================ /** ****************************************************************************** * @file stm8s_tim3.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM3 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM3_H #define __STM8S_TIM3_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup TIM3_Exported_Types * @{ */ /** TIM3 Forced Action */ typedef enum { TIM3_FORCEDACTION_ACTIVE = ((uint8_t)0x50), TIM3_FORCEDACTION_INACTIVE = ((uint8_t)0x40) } TIM3_ForcedAction_TypeDef; #define IS_TIM3_FORCED_ACTION_OK(ACTION) (((ACTION) == TIM3_FORCEDACTION_ACTIVE) || \ ((ACTION) == TIM3_FORCEDACTION_INACTIVE)) /** TIM3 Prescaler */ typedef enum { TIM3_PRESCALER_1 = ((uint8_t)0x00), TIM3_PRESCALER_2 = ((uint8_t)0x01), TIM3_PRESCALER_4 = ((uint8_t)0x02), TIM3_PRESCALER_8 = ((uint8_t)0x03), TIM3_PRESCALER_16 = ((uint8_t)0x04), TIM3_PRESCALER_32 = ((uint8_t)0x05), TIM3_PRESCALER_64 = ((uint8_t)0x06), TIM3_PRESCALER_128 = ((uint8_t)0x07), TIM3_PRESCALER_256 = ((uint8_t)0x08), TIM3_PRESCALER_512 = ((uint8_t)0x09), TIM3_PRESCALER_1024 = ((uint8_t)0x0A), TIM3_PRESCALER_2048 = ((uint8_t)0x0B), TIM3_PRESCALER_4096 = ((uint8_t)0x0C), TIM3_PRESCALER_8192 = ((uint8_t)0x0D), TIM3_PRESCALER_16384 = ((uint8_t)0x0E), TIM3_PRESCALER_32768 = ((uint8_t)0x0F) } TIM3_Prescaler_TypeDef; #define IS_TIM3_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM3_PRESCALER_1 ) || \ ((PRESCALER) == TIM3_PRESCALER_2 ) || \ ((PRESCALER) == TIM3_PRESCALER_4 ) || \ ((PRESCALER) == TIM3_PRESCALER_8 ) || \ ((PRESCALER) == TIM3_PRESCALER_16 ) || \ ((PRESCALER) == TIM3_PRESCALER_32 ) || \ ((PRESCALER) == TIM3_PRESCALER_64 ) || \ ((PRESCALER) == TIM3_PRESCALER_128 ) || \ ((PRESCALER) == TIM3_PRESCALER_256 ) || \ ((PRESCALER) == TIM3_PRESCALER_512 ) || \ ((PRESCALER) == TIM3_PRESCALER_1024 ) || \ ((PRESCALER) == TIM3_PRESCALER_2048 ) || \ ((PRESCALER) == TIM3_PRESCALER_4096 ) || \ ((PRESCALER) == TIM3_PRESCALER_8192 ) || \ ((PRESCALER) == TIM3_PRESCALER_16384 ) || \ ((PRESCALER) == TIM3_PRESCALER_32768 )) /** TIM3 Output Compare and PWM modes */ typedef enum { TIM3_OCMODE_TIMING = ((uint8_t)0x00), TIM3_OCMODE_ACTIVE = ((uint8_t)0x10), TIM3_OCMODE_INACTIVE = ((uint8_t)0x20), TIM3_OCMODE_TOGGLE = ((uint8_t)0x30), TIM3_OCMODE_PWM1 = ((uint8_t)0x60), TIM3_OCMODE_PWM2 = ((uint8_t)0x70) } TIM3_OCMode_TypeDef; #define IS_TIM3_OC_MODE_OK(MODE) (((MODE) == TIM3_OCMODE_TIMING) || \ ((MODE) == TIM3_OCMODE_ACTIVE) || \ ((MODE) == TIM3_OCMODE_INACTIVE) || \ ((MODE) == TIM3_OCMODE_TOGGLE)|| \ ((MODE) == TIM3_OCMODE_PWM1) || \ ((MODE) == TIM3_OCMODE_PWM2)) #define IS_TIM3_OCM_OK(MODE)(((MODE) == TIM3_OCMODE_TIMING) || \ ((MODE) == TIM3_OCMODE_ACTIVE) || \ ((MODE) == TIM3_OCMODE_INACTIVE) || \ ((MODE) == TIM3_OCMODE_TOGGLE)|| \ ((MODE) == TIM3_OCMODE_PWM1) || \ ((MODE) == TIM3_OCMODE_PWM2) || \ ((MODE) == (uint8_t)TIM3_FORCEDACTION_ACTIVE) || \ ((MODE) == (uint8_t)TIM3_FORCEDACTION_INACTIVE)) /** TIM3 One Pulse Mode */ typedef enum { TIM3_OPMODE_SINGLE = ((uint8_t)0x01), TIM3_OPMODE_REPETITIVE = ((uint8_t)0x00) } TIM3_OPMode_TypeDef; #define IS_TIM3_OPM_MODE_OK(MODE) (((MODE) == TIM3_OPMODE_SINGLE) || \ ((MODE) == TIM3_OPMODE_REPETITIVE)) /** TIM3 Channel */ typedef enum { TIM3_CHANNEL_1 = ((uint8_t)0x00), TIM3_CHANNEL_2 = ((uint8_t)0x01) } TIM3_Channel_TypeDef; #define IS_TIM3_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM3_CHANNEL_1) || \ ((CHANNEL) == TIM3_CHANNEL_2)) #define IS_TIM3_PWMI_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM3_CHANNEL_1) || \ ((CHANNEL) == TIM3_CHANNEL_2)) /** TIM3 Output Compare Polarity */ typedef enum { TIM3_OCPOLARITY_HIGH = ((uint8_t)0x00), TIM3_OCPOLARITY_LOW = ((uint8_t)0x22) } TIM3_OCPolarity_TypeDef; #define IS_TIM3_OC_POLARITY_OK(POLARITY) (((POLARITY) == TIM3_OCPOLARITY_HIGH) || \ ((POLARITY) == TIM3_OCPOLARITY_LOW)) /** TIM3 Output Compare states */ typedef enum { TIM3_OUTPUTSTATE_DISABLE = ((uint8_t)0x00), TIM3_OUTPUTSTATE_ENABLE = ((uint8_t)0x11) } TIM3_OutputState_TypeDef; #define IS_TIM3_OUTPUT_STATE_OK(STATE) (((STATE) == TIM3_OUTPUTSTATE_DISABLE) || \ ((STATE) == TIM3_OUTPUTSTATE_ENABLE)) /** TIM3 Input Capture Polarity */ typedef enum { TIM3_ICPOLARITY_RISING = ((uint8_t)0x00), TIM3_ICPOLARITY_FALLING = ((uint8_t)0x44) } TIM3_ICPolarity_TypeDef; #define IS_TIM3_IC_POLARITY_OK(POLARITY) (((POLARITY) == TIM3_ICPOLARITY_RISING) || \ ((POLARITY) == TIM3_ICPOLARITY_FALLING)) /** TIM3 Input Capture Selection */ typedef enum { TIM3_ICSELECTION_DIRECTTI = ((uint8_t)0x01), TIM3_ICSELECTION_INDIRECTTI = ((uint8_t)0x02), TIM3_ICSELECTION_TRGI = ((uint8_t)0x03) } TIM3_ICSelection_TypeDef; #define IS_TIM3_IC_SELECTION_OK(SELECTION) (((SELECTION) == TIM3_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM3_ICSELECTION_INDIRECTTI) || \ ((SELECTION) == TIM3_ICSELECTION_TRGI)) /** TIM3 Input Capture Prescaler */ typedef enum { TIM3_ICPSC_DIV1 = ((uint8_t)0x00), TIM3_ICPSC_DIV2 = ((uint8_t)0x04), TIM3_ICPSC_DIV4 = ((uint8_t)0x08), TIM3_ICPSC_DIV8 = ((uint8_t)0x0C) } TIM3_ICPSC_TypeDef; #define IS_TIM3_IC_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM3_ICPSC_DIV1) || \ ((PRESCALER) == TIM3_ICPSC_DIV2) || \ ((PRESCALER) == TIM3_ICPSC_DIV4) || \ ((PRESCALER) == TIM3_ICPSC_DIV8)) /** TIM3 Input Capture Filer Value */ #define IS_TIM3_IC_FILTER_OK(ICFILTER) ((ICFILTER) <= 0x0F) /** TIM3 interrupt sources */ typedef enum { TIM3_IT_UPDATE = ((uint8_t)0x01), TIM3_IT_CC1 = ((uint8_t)0x02), TIM3_IT_CC2 = ((uint8_t)0x04) } TIM3_IT_TypeDef; #define IS_TIM3_IT_OK(IT) (((IT) != 0x00) && ((IT) <= 0x07)) #define IS_TIM3_GET_IT_OK(IT) (((IT) == TIM3_IT_UPDATE) || \ ((IT) == TIM3_IT_CC1) || \ ((IT) == TIM3_IT_CC2)) /** TIM3 Prescaler Reload Mode */ typedef enum { TIM3_PSCRELOADMODE_UPDATE = ((uint8_t)0x00), TIM3_PSCRELOADMODE_IMMEDIATE = ((uint8_t)0x01) } TIM3_PSCReloadMode_TypeDef; #define IS_TIM3_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM3_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM3_PSCRELOADMODE_IMMEDIATE)) /** TIM3 Event Source */ typedef enum { TIM3_EVENTSOURCE_UPDATE = ((uint8_t)0x01), TIM3_EVENTSOURCE_CC1 = ((uint8_t)0x02), TIM3_EVENTSOURCE_CC2 = ((uint8_t)0x04) } TIM3_EventSource_TypeDef; #define IS_TIM3_EVENT_SOURCE_OK(SOURCE) (((SOURCE) != 0x00)) /** TIM3 Update Source */ typedef enum { TIM3_UPDATESOURCE_GLOBAL = ((uint8_t)0x00), TIM3_UPDATESOURCE_REGULAR = ((uint8_t)0x01) } TIM3_UpdateSource_TypeDef; #define IS_TIM3_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM3_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM3_UPDATESOURCE_REGULAR)) /** TIM3 Flags */ typedef enum { TIM3_FLAG_UPDATE = ((uint16_t)0x0001), TIM3_FLAG_CC1 = ((uint16_t)0x0002), TIM3_FLAG_CC2 = ((uint16_t)0x0004), TIM3_FLAG_CC1OF = ((uint16_t)0x0200), TIM3_FLAG_CC2OF = ((uint16_t)0x0400) } TIM3_FLAG_TypeDef; #define IS_TIM3_GET_FLAG_OK(FLAG) (((FLAG) == TIM3_FLAG_UPDATE) || \ ((FLAG) == TIM3_FLAG_CC1) || \ ((FLAG) == TIM3_FLAG_CC2) || \ ((FLAG) == TIM3_FLAG_CC1OF) || \ ((FLAG) == TIM3_FLAG_CC2OF) ) #define IS_TIM3_CLEAR_FLAG_OK(FLAG) ((((uint16_t)(FLAG) & 0xF9F8) == 0x0000) && ((uint16_t)(FLAG)!= 0x0000)) /** * @} */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM3_Exported_Functions * @{ */ void TIM3_DeInit(void); void TIM3_TimeBaseInit(TIM3_Prescaler_TypeDef TIM3_Prescaler, uint16_t TIM3_Period); void TIM3_OC1Init(TIM3_OCMode_TypeDef TIM3_OCMode, TIM3_OutputState_TypeDef TIM3_OutputState, uint16_t TIM3_Pulse, TIM3_OCPolarity_TypeDef TIM3_OCPolarity); void TIM3_OC2Init(TIM3_OCMode_TypeDef TIM3_OCMode, TIM3_OutputState_TypeDef TIM3_OutputState, uint16_t TIM3_Pulse, TIM3_OCPolarity_TypeDef TIM3_OCPolarity); void TIM3_ICInit(TIM3_Channel_TypeDef TIM3_Channel, TIM3_ICPolarity_TypeDef TIM3_ICPolarity, TIM3_ICSelection_TypeDef TIM3_ICSelection, TIM3_ICPSC_TypeDef TIM3_ICPrescaler, uint8_t TIM3_ICFilter); void TIM3_PWMIConfig(TIM3_Channel_TypeDef TIM3_Channel, TIM3_ICPolarity_TypeDef TIM3_ICPolarity, TIM3_ICSelection_TypeDef TIM3_ICSelection, TIM3_ICPSC_TypeDef TIM3_ICPrescaler, uint8_t TIM3_ICFilter); void TIM3_Cmd(FunctionalState NewState); void TIM3_ITConfig(TIM3_IT_TypeDef TIM3_IT, FunctionalState NewState); void TIM3_InternalClockConfig(void); void TIM3_UpdateDisableConfig(FunctionalState NewState); void TIM3_UpdateRequestConfig(TIM3_UpdateSource_TypeDef TIM3_UpdateSource); void TIM3_SelectOnePulseMode(TIM3_OPMode_TypeDef TIM3_OPMode); void TIM3_PrescalerConfig(TIM3_Prescaler_TypeDef Prescaler, TIM3_PSCReloadMode_TypeDef TIM3_PSCReloadMode); void TIM3_ForcedOC1Config(TIM3_ForcedAction_TypeDef TIM3_ForcedAction); void TIM3_ForcedOC2Config(TIM3_ForcedAction_TypeDef TIM3_ForcedAction); void TIM3_ARRPreloadConfig(FunctionalState NewState); void TIM3_CCPreloadControl(FunctionalState NewState); void TIM3_OC1PreloadConfig(FunctionalState NewState); void TIM3_OC2PreloadConfig(FunctionalState NewState); void TIM3_GenerateEvent(TIM3_EventSource_TypeDef TIM3_EventSource); void TIM3_OC1PolarityConfig(TIM3_OCPolarity_TypeDef TIM3_OCPolarity); void TIM3_OC2PolarityConfig(TIM3_OCPolarity_TypeDef TIM3_OCPolarity); void TIM3_CCxCmd(TIM3_Channel_TypeDef TIM3_Channel, FunctionalState NewState); void TIM3_SelectOCxM(TIM3_Channel_TypeDef TIM3_Channel, TIM3_OCMode_TypeDef TIM3_OCMode); void TIM3_SetCounter(uint16_t Counter); void TIM3_SetAutoreload(uint16_t Autoreload); void TIM3_SetCompare1(uint16_t Compare1); void TIM3_SetCompare2(uint16_t Compare2); void TIM3_SetIC1Prescaler(TIM3_ICPSC_TypeDef TIM3_IC1Prescaler); void TIM3_SetIC2Prescaler(TIM3_ICPSC_TypeDef TIM3_IC2Prescaler); uint16_t TIM3_GetCapture1(void); uint16_t TIM3_GetCapture2(void); uint16_t TIM3_GetCounter(void); TIM3_Prescaler_TypeDef TIM3_GetPrescaler(void); FlagStatus TIM3_GetFlagStatus(TIM3_FLAG_TypeDef TIM3_FLAG); void TIM3_ClearFlag(TIM3_FLAG_TypeDef TIM3_FLAG); ITStatus TIM3_GetITStatus(TIM3_IT_TypeDef TIM3_IT); void TIM3_ClearITPendingBit(TIM3_IT_TypeDef TIM3_IT); /** * @} */ #endif /* __STM8S_TIM3_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim4.h ================================================ /** ****************************************************************************** * @file stm8s_tim4.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM4 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM4_H #define __STM8S_TIM4_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup TIM4_Exported_Types * @{ */ /** TIM4 Prescaler */ typedef enum { TIM4_PRESCALER_1 = ((uint8_t)0x00), TIM4_PRESCALER_2 = ((uint8_t)0x01), TIM4_PRESCALER_4 = ((uint8_t)0x02), TIM4_PRESCALER_8 = ((uint8_t)0x03), TIM4_PRESCALER_16 = ((uint8_t)0x04), TIM4_PRESCALER_32 = ((uint8_t)0x05), TIM4_PRESCALER_64 = ((uint8_t)0x06), TIM4_PRESCALER_128 = ((uint8_t)0x07) } TIM4_Prescaler_TypeDef; #define IS_TIM4_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM4_PRESCALER_1 ) || \ ((PRESCALER) == TIM4_PRESCALER_2 ) || \ ((PRESCALER) == TIM4_PRESCALER_4 ) || \ ((PRESCALER) == TIM4_PRESCALER_8 ) || \ ((PRESCALER) == TIM4_PRESCALER_16 ) || \ ((PRESCALER) == TIM4_PRESCALER_32 ) || \ ((PRESCALER) == TIM4_PRESCALER_64 ) || \ ((PRESCALER) == TIM4_PRESCALER_128 ) ) /** TIM4 One Pulse Mode */ typedef enum { TIM4_OPMODE_SINGLE = ((uint8_t)0x01), TIM4_OPMODE_REPETITIVE = ((uint8_t)0x00) } TIM4_OPMode_TypeDef; #define IS_TIM4_OPM_MODE_OK(MODE) (((MODE) == TIM4_OPMODE_SINGLE) || \ ((MODE) == TIM4_OPMODE_REPETITIVE)) /** TIM4 Prescaler Reload Mode */ typedef enum { TIM4_PSCRELOADMODE_UPDATE = ((uint8_t)0x00), TIM4_PSCRELOADMODE_IMMEDIATE = ((uint8_t)0x01) } TIM4_PSCReloadMode_TypeDef; #define IS_TIM4_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM4_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM4_PSCRELOADMODE_IMMEDIATE)) /** TIM4 Update Source */ typedef enum { TIM4_UPDATESOURCE_GLOBAL = ((uint8_t)0x00), TIM4_UPDATESOURCE_REGULAR = ((uint8_t)0x01) } TIM4_UpdateSource_TypeDef; #define IS_TIM4_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM4_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM4_UPDATESOURCE_REGULAR)) /** TIM4 Event Source */ typedef enum { TIM4_EVENTSOURCE_UPDATE = ((uint8_t)0x01) }TIM4_EventSource_TypeDef; #define IS_TIM4_EVENT_SOURCE_OK(SOURCE) (((SOURCE) == 0x01)) /** TIM4 Flags */ typedef enum { TIM4_FLAG_UPDATE = ((uint8_t)0x01) }TIM4_FLAG_TypeDef; #define IS_TIM4_GET_FLAG_OK(FLAG) ((FLAG) == TIM4_FLAG_UPDATE) /** TIM4 interrupt sources */ typedef enum { TIM4_IT_UPDATE = ((uint8_t)0x01) }TIM4_IT_TypeDef; #define IS_TIM4_IT_OK(IT) ((IT) == TIM4_IT_UPDATE) /** * @} */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM4_Exported_Functions * @{ */ void TIM4_DeInit(void); void TIM4_TimeBaseInit(TIM4_Prescaler_TypeDef TIM4_Prescaler, uint8_t TIM4_Period); void TIM4_Cmd(FunctionalState NewState); void TIM4_ITConfig(TIM4_IT_TypeDef TIM4_IT, FunctionalState NewState); void TIM4_UpdateDisableConfig(FunctionalState NewState); void TIM4_UpdateRequestConfig(TIM4_UpdateSource_TypeDef TIM4_UpdateSource); void TIM4_SelectOnePulseMode(TIM4_OPMode_TypeDef TIM4_OPMode); void TIM4_PrescalerConfig(TIM4_Prescaler_TypeDef Prescaler, TIM4_PSCReloadMode_TypeDef TIM4_PSCReloadMode); void TIM4_ARRPreloadConfig(FunctionalState NewState); void TIM4_GenerateEvent(TIM4_EventSource_TypeDef TIM4_EventSource); void TIM4_SetCounter(uint8_t Counter); void TIM4_SetAutoreload(uint8_t Autoreload); uint8_t TIM4_GetCounter(void); TIM4_Prescaler_TypeDef TIM4_GetPrescaler(void); FlagStatus TIM4_GetFlagStatus(TIM4_FLAG_TypeDef TIM4_FLAG); void TIM4_ClearFlag(TIM4_FLAG_TypeDef TIM4_FLAG); ITStatus TIM4_GetITStatus(TIM4_IT_TypeDef TIM4_IT); void TIM4_ClearITPendingBit(TIM4_IT_TypeDef TIM4_IT); /** * @} */ #endif /* __STM8S_TIM4_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim5.h ================================================ /** ****************************************************************************** * @file stm8s_tim5.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM5 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM5_H #define __STM8S_TIM5_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** TIM5 Forced Action */ typedef enum { TIM5_FORCEDACTION_ACTIVE =((uint8_t)0x50), TIM5_FORCEDACTION_INACTIVE =((uint8_t)0x40) }TIM5_ForcedAction_TypeDef; #define IS_TIM5_FORCED_ACTION_OK(ACTION) (((ACTION) == TIM5_FORCEDACTION_ACTIVE) || \ ((ACTION) == TIM5_FORCEDACTION_INACTIVE)) /** TIM5 Prescaler */ typedef enum { TIM5_PRESCALER_1 =((uint8_t)0x00), TIM5_PRESCALER_2 =((uint8_t)0x01), TIM5_PRESCALER_4 =((uint8_t)0x02), TIM5_PRESCALER_8 =((uint8_t)0x03), TIM5_PRESCALER_16 =((uint8_t)0x04), TIM5_PRESCALER_32 =((uint8_t)0x05), TIM5_PRESCALER_64 =((uint8_t)0x06), TIM5_PRESCALER_128 =((uint8_t)0x07), TIM5_PRESCALER_256 =((uint8_t)0x08), TIM5_PRESCALER_512 =((uint8_t)0x09), TIM5_PRESCALER_1024 =((uint8_t)0x0A), TIM5_PRESCALER_2048 =((uint8_t)0x0B), TIM5_PRESCALER_4096 =((uint8_t)0x0C), TIM5_PRESCALER_8192 =((uint8_t)0x0D), TIM5_PRESCALER_16384 =((uint8_t)0x0E), TIM5_PRESCALER_32768 =((uint8_t)0x0F) }TIM5_Prescaler_TypeDef; #define IS_TIM5_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM5_PRESCALER_1) || \ ((PRESCALER) == TIM5_PRESCALER_2 ) || \ ((PRESCALER) == TIM5_PRESCALER_4 ) || \ ((PRESCALER) == TIM5_PRESCALER_8 ) || \ ((PRESCALER) == TIM5_PRESCALER_16 ) || \ ((PRESCALER) == TIM5_PRESCALER_32 ) || \ ((PRESCALER) == TIM5_PRESCALER_64 ) || \ ((PRESCALER) == TIM5_PRESCALER_128 ) || \ ((PRESCALER) == TIM5_PRESCALER_256 ) || \ ((PRESCALER) == TIM5_PRESCALER_512 ) || \ ((PRESCALER) == TIM5_PRESCALER_1024 ) || \ ((PRESCALER) == TIM5_PRESCALER_2048 ) || \ ((PRESCALER) == TIM5_PRESCALER_4096 ) || \ ((PRESCALER) == TIM5_PRESCALER_8192 ) || \ ((PRESCALER) == TIM5_PRESCALER_16384 ) || \ ((PRESCALER) == TIM5_PRESCALER_32768 )) /** TIM5 Output Compare and PWM modes */ typedef enum { TIM5_OCMODE_TIMING =((uint8_t)0x00), TIM5_OCMODE_ACTIVE =((uint8_t)0x10), TIM5_OCMODE_INACTIVE =((uint8_t)0x20), TIM5_OCMODE_TOGGLE =((uint8_t)0x30), TIM5_OCMODE_PWM1 =((uint8_t)0x60), TIM5_OCMODE_PWM2 =((uint8_t)0x70) }TIM5_OCMode_TypeDef; #define IS_TIM5_OC_MODE_OK(MODE) (((MODE) == TIM5_OCMODE_TIMING) || \ ((MODE) == TIM5_OCMODE_ACTIVE) || \ ((MODE) == TIM5_OCMODE_INACTIVE) || \ ((MODE) == TIM5_OCMODE_TOGGLE)|| \ ((MODE) == TIM5_OCMODE_PWM1) || \ ((MODE) == TIM5_OCMODE_PWM2)) #define IS_TIM5_OCM_OK(MODE)(((MODE) == TIM5_OCMODE_TIMING) || \ ((MODE) == TIM5_OCMODE_ACTIVE) || \ ((MODE) == TIM5_OCMODE_INACTIVE) || \ ((MODE) == TIM5_OCMODE_TOGGLE)|| \ ((MODE) == TIM5_OCMODE_PWM1) || \ ((MODE) == TIM5_OCMODE_PWM2) || \ ((MODE) == (uint8_t)TIM5_FORCEDACTION_ACTIVE) || \ ((MODE) == (uint8_t)TIM5_FORCEDACTION_INACTIVE)) /** TIM5 One Pulse Mode */ typedef enum { TIM5_OPMODE_SINGLE =((uint8_t)0x01), TIM5_OPMODE_REPETITIVE =((uint8_t)0x00) }TIM5_OPMode_TypeDef; #define IS_TIM5_OPM_MODE_OK(MODE) (((MODE) == TIM5_OPMODE_SINGLE) || \ ((MODE) == TIM5_OPMODE_REPETITIVE)) /** TIM5 Channel */ typedef enum { TIM5_CHANNEL_1 =((uint8_t)0x00), TIM5_CHANNEL_2 =((uint8_t)0x01), TIM5_CHANNEL_3 =((uint8_t)0x02) }TIM5_Channel_TypeDef; #define IS_TIM5_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM5_CHANNEL_1) || \ ((CHANNEL) == TIM5_CHANNEL_2) || \ ((CHANNEL) == TIM5_CHANNEL_3)) #define IS_TIM5_PWMI_CHANNEL_OK(CHANNEL) (((CHANNEL) == TIM5_CHANNEL_1) || \ ((CHANNEL) == TIM5_CHANNEL_2)) /** TIM5 Output Compare Polarity */ typedef enum { TIM5_OCPOLARITY_HIGH =((uint8_t)0x00), TIM5_OCPOLARITY_LOW =((uint8_t)0x22) }TIM5_OCPolarity_TypeDef; #define IS_TIM5_OC_POLARITY_OK(POLARITY) (((POLARITY) == TIM5_OCPOLARITY_HIGH) || \ ((POLARITY) == TIM5_OCPOLARITY_LOW)) /** TIM5 Output Compare states */ typedef enum { TIM5_OUTPUTSTATE_DISABLE =((uint8_t)0x00), TIM5_OUTPUTSTATE_ENABLE =((uint8_t)0x11) }TIM5_OutputState_TypeDef; #define IS_TIM5_OUTPUT_STATE_OK(STATE) (((STATE) == TIM5_OUTPUTSTATE_DISABLE) || \ ((STATE) == TIM5_OUTPUTSTATE_ENABLE)) /** TIM5 Input Capture Polarity */ typedef enum { TIM5_ICPOLARITY_RISING =((uint8_t)0x00), TIM5_ICPOLARITY_FALLING =((uint8_t)0x44) }TIM5_ICPolarity_TypeDef; #define IS_TIM5_IC_POLARITY_OK(POLARITY) (((POLARITY) == TIM5_ICPOLARITY_RISING) || \ ((POLARITY) == TIM5_ICPOLARITY_FALLING)) /** TIM5 Input Capture Selection */ typedef enum { TIM5_ICSELECTION_DIRECTTI =((uint8_t)0x01), TIM5_ICSELECTION_INDIRECTTI =((uint8_t)0x02), TIM5_ICSELECTION_TRGI =((uint8_t)0x03) }TIM5_ICSelection_TypeDef; #define IS_TIM5_IC_SELECTION_OK(SELECTION) (((SELECTION) == TIM5_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM5_ICSELECTION_INDIRECTTI) || \ ((SELECTION) == TIM5_ICSELECTION_TRGI)) #define IS_TIM5_IC_SELECTION1_OK(SELECTION) (((SELECTION) == TIM5_ICSELECTION_DIRECTTI) || \ ((SELECTION) == TIM5_ICSELECTION_TRGI)) /** TIM5 Input Capture Prescaler */ typedef enum { TIM5_ICPSC_DIV1 =((uint8_t)0x00), TIM5_ICPSC_DIV2 =((uint8_t)0x04), TIM5_ICPSC_DIV4 =((uint8_t)0x08), TIM5_ICPSC_DIV8 =((uint8_t)0x0C) }TIM5_ICPSC_TypeDef; #define IS_TIM5_IC_PRESCALER_OK(PRESCALER) (((PRESCALER) == TIM5_ICPSC_DIV1) || \ ((PRESCALER) == TIM5_ICPSC_DIV2) || \ ((PRESCALER) == TIM5_ICPSC_DIV4) || \ ((PRESCALER) == TIM5_ICPSC_DIV8)) /** TIM5 Input Capture Filer Value */ #define IS_TIM5_IC_FILTER_OK(ICFILTER) ((ICFILTER) <= 0x0F) /** TIM5 interrupt sources */ typedef enum { TIM5_IT_UPDATE =((uint8_t)0x01), TIM5_IT_CC1 =((uint8_t)0x02), TIM5_IT_CC2 =((uint8_t)0x04), TIM5_IT_CC3 =((uint8_t)0x08), TIM5_IT_TRIGGER = ((uint8_t)0x40) }TIM5_IT_TypeDef; #define IS_TIM5_IT_OK(IT) (((IT) != 0x00) && ((IT) <= 0x4F)) #define IS_TIM5_GET_IT_OK(IT) (((IT) == TIM5_IT_UPDATE) || \ ((IT) == TIM5_IT_CC1) || \ ((IT) == TIM5_IT_CC2) || \ ((IT) == TIM5_IT_CC3) || \ ((IT) == TIM5_IT_TRIGGER)) /** TIM5 Prescaler Reload Mode */ typedef enum { TIM5_PSCRELOADMODE_UPDATE =((uint8_t)0x00), TIM5_PSCRELOADMODE_IMMEDIATE =((uint8_t)0x01) }TIM5_PSCReloadMode_TypeDef; #define IS_TIM5_PRESCALER_RELOAD_OK(RELOAD) (((RELOAD) == TIM5_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM5_PSCRELOADMODE_IMMEDIATE)) /** TIM5 Event Source */ typedef enum { TIM5_EVENTSOURCE_UPDATE =((uint8_t)0x01), TIM5_EVENTSOURCE_CC1 =((uint8_t)0x02), TIM5_EVENTSOURCE_CC2 =((uint8_t)0x04), TIM5_EVENTSOURCE_CC3 =((uint8_t)0x08), TIM5_EVENTSOURCE_TRIGGER = ((uint8_t)0x40) }TIM5_EventSource_TypeDef; #define IS_TIM5_EVENT_SOURCE_OK(SOURCE) (((SOURCE) != 0x00)) /** TIM5 Update Source */ typedef enum { TIM5_UPDATESOURCE_GLOBAL =((uint8_t)0x00), TIM5_UPDATESOURCE_REGULAR =((uint8_t)0x01) }TIM5_UpdateSource_TypeDef; #define IS_TIM5_UPDATE_SOURCE_OK(SOURCE) (((SOURCE) == TIM5_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM5_UPDATESOURCE_REGULAR)) /** * @brief TIM5 Trigger Output Source */ typedef enum { TIM5_TRGOSOURCE_RESET = ((uint8_t)0x00), /*!< Trigger Output source = Reset*/ TIM5_TRGOSOURCE_ENABLE = ((uint8_t)0x10), /*!< Trigger Output source = TIM5 is enabled*/ TIM5_TRGOSOURCE_UPDATE = ((uint8_t)0x20), /*!< Trigger Output source = Update event*/ TIM5_TRGOSOURCE_OC1 = ((uint8_t)0x30), /*!< Trigger Output source = output compare channel1 */ TIM5_TRGOSOURCE_OC1REF = ((uint8_t)0x40), /*!< Trigger Output source = output compare channel 1 reference */ TIM5_TRGOSOURCE_OC2REF = ((uint8_t)0x50) /*!< Trigger Output source = output compare channel 2 reference */ }TIM5_TRGOSource_TypeDef; /** * @brief Macro TIM5 TRGO source */ #define IS_TIM5_TRGO_SOURCE_OK(SOURCE) \ (((SOURCE) == TIM5_TRGOSOURCE_RESET) || \ ((SOURCE) == TIM5_TRGOSOURCE_ENABLE) || \ ((SOURCE) == TIM5_TRGOSOURCE_UPDATE) || \ ((SOURCE) == TIM5_TRGOSOURCE_OC1) || \ ((SOURCE) == TIM5_TRGOSOURCE_OC1REF) || \ ((SOURCE) == TIM5_TRGOSOURCE_OC2REF)) /** TIM5 Flags */ typedef enum { TIM5_FLAG_UPDATE =((uint16_t)0x0001), TIM5_FLAG_CC1 =((uint16_t)0x0002), TIM5_FLAG_CC2 =((uint16_t)0x0004), TIM5_FLAG_CC3 =((uint16_t)0x0008), TIM5_FLAG_TRIGGER = ((uint16_t)0x0040), TIM5_FLAG_CC1OF =((uint16_t)0x0200), TIM5_FLAG_CC2OF =((uint16_t)0x0400), TIM5_FLAG_CC3OF =((uint16_t)0x0800) }TIM5_FLAG_TypeDef; #define IS_TIM5_GET_FLAG_OK(FLAG) (((FLAG) == TIM5_FLAG_UPDATE) || \ ((FLAG) == TIM5_FLAG_CC1) || \ ((FLAG) == TIM5_FLAG_CC2) || \ ((FLAG) == TIM5_FLAG_CC3) || \ ((FLAG) == TIM5_FLAG_TRIGGER) || \ ((FLAG) == TIM5_FLAG_CC1OF) || \ ((FLAG) == TIM5_FLAG_CC2OF) || \ ((FLAG) == TIM5_FLAG_CC3OF)) #define IS_TIM5_CLEAR_FLAG_OK(FLAG) ((((uint16_t)(FLAG) & 0xF1F0) == 0x0000) && ((uint16_t)(FLAG) != 0x0000)) /** * @brief TIM5 Slave Mode */ typedef enum { TIM5_SLAVEMODE_RESET = ((uint8_t)0x04), /*!< Slave Mode Selection = Reset*/ TIM5_SLAVEMODE_GATED = ((uint8_t)0x05), /*!< Slave Mode Selection = Gated*/ TIM5_SLAVEMODE_TRIGGER = ((uint8_t)0x06), /*!< Slave Mode Selection = Trigger*/ TIM5_SLAVEMODE_EXTERNAL1 = ((uint8_t)0x07) /*!< Slave Mode Selection = External 1*/ }TIM5_SlaveMode_TypeDef; /** * @brief Macro TIM5 Slave mode */ #define IS_TIM5_SLAVE_MODE_OK(MODE) \ (((MODE) == TIM5_SLAVEMODE_RESET) || \ ((MODE) == TIM5_SLAVEMODE_GATED) || \ ((MODE) == TIM5_SLAVEMODE_TRIGGER) || \ ((MODE) == TIM5_SLAVEMODE_EXTERNAL1)) /** * @brief TIM5 Internal Trigger Selection */ typedef enum { TIM5_TS_TIM6 = ((uint8_t)0x00), /*!< TRIG Input source = TIM6 TRIG Output */ TIM5_TS_TIM1 = ((uint8_t)0x03) /*!< TRIG Input source = TIM1 TRIG Output */ }TIM5_TS_TypeDef; /** * @brief Macro TIM5 Trigger Selection */ #define IS_TIM5_TRIGGER_SELECTION_OK(SELECTION) \ (((SELECTION) == TIM5_TS_TIM6) || \ ((SELECTION) == TIM5_TS_TIM1) ) #define IS_TIM5_TIX_TRIGGER_SELECTION_OK(SELECTION) \ (((SELECTION) == TIM5_TS_TI1F_ED) || \ ((SELECTION) == TIM5_TS_TI1FP1) || \ ((SELECTION) == TIM5_TS_TI2FP2)) /** * @brief TIM5 Encoder Mode */ typedef enum { TIM5_ENCODERMODE_TI1 = ((uint8_t)0x01), /*!< Encoder mode 1*/ TIM5_ENCODERMODE_TI2 = ((uint8_t)0x02), /*!< Encoder mode 2*/ TIM5_ENCODERMODE_TI12 = ((uint8_t)0x03) /*!< Encoder mode 3*/ }TIM5_EncoderMode_TypeDef; /** * @brief Macro TIM5 encoder mode */ #define IS_TIM5_ENCODER_MODE_OK(MODE) \ (((MODE) == TIM5_ENCODERMODE_TI1) || \ ((MODE) == TIM5_ENCODERMODE_TI2) || \ ((MODE) == TIM5_ENCODERMODE_TI12)) /** * @brief TIM5 External Trigger Prescaler */ typedef enum { TIM5_EXTTRGPSC_OFF = ((uint8_t)0x00), /*!< No External Trigger prescaler */ TIM5_EXTTRGPSC_DIV2 = ((uint8_t)0x10), /*!< External Trigger prescaler = 2 (ETRP frequency divided by 2) */ TIM5_EXTTRGPSC_DIV4 = ((uint8_t)0x20), /*!< External Trigger prescaler = 4 (ETRP frequency divided by 4) */ TIM5_EXTTRGPSC_DIV8 = ((uint8_t)0x30) /*!< External Trigger prescaler = 8 (ETRP frequency divided by 8) */ }TIM5_ExtTRGPSC_TypeDef; /** * @brief Macro TIM5 external trigger prescaler */ #define IS_TIM5_EXT_PRESCALER_OK(PRESCALER) \ (((PRESCALER) == TIM5_EXTTRGPSC_OFF) || \ ((PRESCALER) == TIM5_EXTTRGPSC_DIV2) || \ ((PRESCALER) == TIM5_EXTTRGPSC_DIV4) || \ ((PRESCALER) == TIM5_EXTTRGPSC_DIV8)) /** * @brief TIM5 External Trigger Polarity */ typedef enum { TIM5_EXTTRGPOLARITY_INVERTED = ((uint8_t)0x80), /*!< External Trigger Polarity = inverted */ TIM5_EXTTRGPOLARITY_NONINVERTED = ((uint8_t)0x00) /*!< External Trigger Polarity = non inverted */ }TIM5_ExtTRGPolarity_TypeDef; /** * @brief Macro TIM5 Trigger Polarity */ #define IS_TIM5_EXT_POLARITY_OK(POLARITY) \ (((POLARITY) == TIM5_EXTTRGPOLARITY_INVERTED) || \ ((POLARITY) == TIM5_EXTTRGPOLARITY_NONINVERTED)) /** * @brief Macro TIM5 External Trigger Filter */ #define IS_TIM5_EXT_FILTER_OK(EXTFILTER) ((EXTFILTER) <= 0x0F) /** * @} */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM5_Exported_Functions * @{ */ void TIM5_DeInit(void); void TIM5_TimeBaseInit(TIM5_Prescaler_TypeDef TIM5_Prescaler, uint16_t TIM5_Period); void TIM5_OC1Init(TIM5_OCMode_TypeDef TIM5_OCMode, TIM5_OutputState_TypeDef TIM5_OutputState,uint16_t TIM5_Pulse, TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_OC2Init(TIM5_OCMode_TypeDef TIM5_OCMode, TIM5_OutputState_TypeDef TIM5_OutputState,uint16_t TIM5_Pulse, TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_OC3Init(TIM5_OCMode_TypeDef TIM5_OCMode, TIM5_OutputState_TypeDef TIM5_OutputState,uint16_t TIM5_Pulse, TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_ICInit(TIM5_Channel_TypeDef TIM5_Channel, TIM5_ICPolarity_TypeDef TIM5_ICPolarity, TIM5_ICSelection_TypeDef TIM5_ICSelection, TIM5_ICPSC_TypeDef TIM5_ICPrescaler, uint8_t TIM5_ICFilter); void TIM5_PWMIConfig(TIM5_Channel_TypeDef TIM5_Channel, TIM5_ICPolarity_TypeDef TIM5_ICPolarity, TIM5_ICSelection_TypeDef TIM5_ICSelection, TIM5_ICPSC_TypeDef TIM5_ICPrescaler, uint8_t TIM5_ICFilter); void TIM5_Cmd(FunctionalState NewState); void TIM5_ITConfig(TIM5_IT_TypeDef TIM5_IT, FunctionalState NewState); void TIM5_InternalClockConfig(void); void TIM5_UpdateDisableConfig(FunctionalState NewState); void TIM5_UpdateRequestConfig(TIM5_UpdateSource_TypeDef TIM5_UpdateSource); void TIM5_SelectOnePulseMode(TIM5_OPMode_TypeDef TIM5_OPMode); void TIM5_PrescalerConfig(TIM5_Prescaler_TypeDef Prescaler, TIM5_PSCReloadMode_TypeDef TIM5_PSCReloadMode); void TIM5_SelectOutputTrigger(TIM5_TRGOSource_TypeDef TIM5_TRGOSource); void TIM5_ForcedOC1Config(TIM5_ForcedAction_TypeDef TIM5_ForcedAction); void TIM5_ForcedOC2Config(TIM5_ForcedAction_TypeDef TIM5_ForcedAction); void TIM5_ForcedOC3Config(TIM5_ForcedAction_TypeDef TIM5_ForcedAction); void TIM5_ARRPreloadConfig(FunctionalState NewState); void TIM5_CCPreloadControl(FunctionalState NewState); void TIM5_OC1PreloadConfig(FunctionalState NewState); void TIM5_OC2PreloadConfig(FunctionalState NewState); void TIM5_OC3PreloadConfig(FunctionalState NewState); void TIM5_GenerateEvent(TIM5_EventSource_TypeDef TIM5_EventSource); void TIM5_OC1PolarityConfig(TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_OC2PolarityConfig(TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_OC3PolarityConfig(TIM5_OCPolarity_TypeDef TIM5_OCPolarity); void TIM5_CCxCmd(TIM5_Channel_TypeDef TIM5_Channel, FunctionalState NewState); void TIM5_SelectOCxM(TIM5_Channel_TypeDef TIM5_Channel, TIM5_OCMode_TypeDef TIM5_OCMode); void TIM5_SetCounter(uint16_t Counter); void TIM5_SetAutoreload(uint16_t Autoreload); void TIM5_SetCompare1(uint16_t Compare1); void TIM5_SetCompare2(uint16_t Compare2); void TIM5_SetCompare3(uint16_t Compare3); void TIM5_SetIC1Prescaler(TIM5_ICPSC_TypeDef TIM5_IC1Prescaler); void TIM5_SetIC2Prescaler(TIM5_ICPSC_TypeDef TIM5_IC2Prescaler); void TIM5_SetIC3Prescaler(TIM5_ICPSC_TypeDef TIM5_IC3Prescaler); uint16_t TIM5_GetCapture1(void); uint16_t TIM5_GetCapture2(void); uint16_t TIM5_GetCapture3(void); uint16_t TIM5_GetCounter(void); TIM5_Prescaler_TypeDef TIM5_GetPrescaler(void); FlagStatus TIM5_GetFlagStatus(TIM5_FLAG_TypeDef TIM5_FLAG); void TIM5_ClearFlag(TIM5_FLAG_TypeDef TIM5_FLAG); ITStatus TIM5_GetITStatus(TIM5_IT_TypeDef TIM5_IT); void TIM5_ClearITPendingBit(TIM5_IT_TypeDef TIM5_IT); void TIM5_SelectInputTrigger(TIM5_TS_TypeDef TIM5_InputTriggerSource); void TIM5_SelectSlaveMode(TIM5_SlaveMode_TypeDef TIM5_SlaveMode); void TIM5_EncoderInterfaceConfig(TIM5_EncoderMode_TypeDef TIM5_EncoderMode, TIM5_ICPolarity_TypeDef TIM5_IC1Polarity,TIM5_ICPolarity_TypeDef TIM5_IC2Polarity); /** * @} */ #endif /* __STM8S_TIM5_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_tim6.h ================================================ /** ****************************************************************************** * @file stm8s_tim6.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the TIM6 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_TIM6_H #define __STM8S_TIM6_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported variables ------------------------------------------------------- */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup TIM6_Exported_Types * @{ */ /** * @brief TIM6 Prescaler */ typedef enum { TIM6_PRESCALER_1 = ((uint8_t)0x00), /*!< Time base Prescaler = 1 (No effect)*/ TIM6_PRESCALER_2 = ((uint8_t)0x01), /*!< Time base Prescaler = 2 */ TIM6_PRESCALER_4 = ((uint8_t)0x02), /*!< Time base Prescaler = 4 */ TIM6_PRESCALER_8 = ((uint8_t)0x03), /*!< Time base Prescaler = 8 */ TIM6_PRESCALER_16 = ((uint8_t)0x04), /*!< Time base Prescaler = 16 */ TIM6_PRESCALER_32 = ((uint8_t)0x05), /*!< Time base Prescaler = 32 */ TIM6_PRESCALER_64 = ((uint8_t)0x06), /*!< Time base Prescaler = 64 */ TIM6_PRESCALER_128 = ((uint8_t)0x07) /*!< Time base Prescaler = 128 */ }TIM6_Prescaler_TypeDef; /** * @brief TIM6 One Pulse Mode */ typedef enum { TIM6_OPMODE_SINGLE = ((uint8_t)0x01), /*!< Single one Pulse mode (OPM Active) */ TIM6_OPMODE_REPETITIVE = ((uint8_t)0x00) /*!< Repetitive Pulse mode (OPM inactive) */ }TIM6_OPMode_TypeDef; /** * @brief TIM6 Prescaler Reload Mode */ typedef enum { TIM6_PSCRELOADMODE_UPDATE =((uint8_t)0x00), /*!< Prescaler value is reloaded at every update*/ TIM6_PSCRELOADMODE_IMMEDIATE =((uint8_t)0x01) /*!< Prescaler value is reloaded immediately*/ }TIM6_PSCReloadMode_TypeDef; /** * @brief TIM6 Update Source */ typedef enum { TIM6_UPDATESOURCE_GLOBAL =((uint8_t)0x00), /*!< Global Update request source */ TIM6_UPDATESOURCE_REGULAR =((uint8_t)0x01) /*!< Regular Update request source */ }TIM6_UpdateSource_TypeDef; /** * @brief TIM6 Event Source */ typedef enum { TIM6_EVENTSOURCE_UPDATE = ((uint8_t)0x01), /*!< Update Event*/ TIM6_EVENTSOURCE_TRIGGER = ((uint8_t)0x40) /*!< Trigger Event*/ }TIM6_EventSource_TypeDef; /** * @brief TIM6 Trigger Output Source */ typedef enum { TIM6_TRGOSOURCE_RESET = ((uint8_t)0x00), /*!< Trigger Output source = Reset*/ TIM6_TRGOSOURCE_ENABLE = ((uint8_t)0x10), /*!< Trigger Output source = TIM5 is enabled*/ TIM6_TRGOSOURCE_UPDATE = ((uint8_t)0x20) /*!< Trigger Output source = Update event*/ }TIM6_TRGOSource_TypeDef; /** * @brief TIM6 Slave Mode */ typedef enum { TIM6_SLAVEMODE_DISABLE = ((uint8_t)0x00), /*!< Disable slave mode to clock the prescaler directly with the internal clock */ TIM6_SLAVEMODE_RESET = ((uint8_t)0x04), /*!< Slave Mode Selection = Reset*/ TIM6_SLAVEMODE_GATED = ((uint8_t)0x05), /*!< Slave Mode Selection = Gated*/ TIM6_SLAVEMODE_TRIGGER = ((uint8_t)0x06), /*!< Slave Mode Selection = Trigger*/ TIM6_SLAVEMODE_EXTERNAL1 = ((uint8_t)0x07) /*!< Slave Mode Selection = External 1*/ }TIM6_SlaveMode_TypeDef; /** * @brief TIM6 Flags */ typedef enum { TIM6_FLAG_UPDATE = ((uint8_t)0x01), /*!< Update Flag */ TIM6_FLAG_TRIGGER = ((uint8_t)0x40) /*!< Trigger Flag */ }TIM6_FLAG_TypeDef; /** * @brief TIM6 interrupt sources */ typedef enum { TIM6_IT_UPDATE = ((uint8_t)0x01), /*!< Update Interrupt*/ TIM6_IT_TRIGGER = ((uint8_t)0x40) /*!< Trigger Interrupt*/ }TIM6_IT_TypeDef; /** * @brief TIM6 Internal Trigger Selection */ typedef enum { TIM6_TS_TIM1 = ((uint8_t)0x20),/*!< TRIG Input source = TIM1 TRIG Output */ TIM6_TS_TIM5 = ((uint8_t)0x30) /*!< TRIG Input source = TIM5 TRIG Output */ }TIM6_TS_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup TIM6_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro TIM6 Prescaler */ #define IS_TIM6_PRESCALER_OK(PRESCALER) \ (((PRESCALER) == TIM6_PRESCALER_1) || \ ((PRESCALER) == TIM6_PRESCALER_2) || \ ((PRESCALER) == TIM6_PRESCALER_4) || \ ((PRESCALER) == TIM6_PRESCALER_8) || \ ((PRESCALER) == TIM6_PRESCALER_16) || \ ((PRESCALER) == TIM6_PRESCALER_32) || \ ((PRESCALER) == TIM6_PRESCALER_64) || \ ((PRESCALER) == TIM6_PRESCALER_128)) /** * @brief Macro TIM6 One Pulse Mode */ #define IS_TIM6_OPM_MODE_OK(MODE) \ (((MODE) == TIM6_OPMODE_SINGLE) || \ ((MODE) == TIM6_OPMODE_REPETITIVE)) /** * @brief Macro TIM6 Prescaler reload */ #define IS_TIM6_PRESCALER_RELOAD_OK(RELOAD) \ (((RELOAD) == TIM6_PSCRELOADMODE_UPDATE) || \ ((RELOAD) == TIM6_PSCRELOADMODE_IMMEDIATE)) /** * @brief Macro TIM6 Update source */ #define IS_TIM6_UPDATE_SOURCE_OK(SOURCE) \ (((SOURCE) == TIM6_UPDATESOURCE_GLOBAL) || \ ((SOURCE) == TIM6_UPDATESOURCE_REGULAR)) /** * @brief Macro TIM6 Event source */ #define IS_TIM6_EVENT_SOURCE_OK(SOURCE) \ ((((SOURCE) & (uint8_t)0xBE) == 0x00) && \ ((SOURCE) != 0x00)) /** * @brief Macro TIM6 TRGO source */ #define IS_TIM6_TRGO_SOURCE_OK(SOURCE) \ (((SOURCE) == TIM6_TRGOSOURCE_RESET) || \ ((SOURCE) == TIM6_TRGOSOURCE_ENABLE)|| \ ((SOURCE) == TIM6_TRGOSOURCE_UPDATE)) /** * @brief Macro TIM6 Slave mode */ #define IS_TIM6_SLAVE_MODE_OK(MODE) \ (((MODE) == TIM6_SLAVEMODE_DISABLE) || \ ((MODE) == TIM6_SLAVEMODE_RESET) || \ ((MODE) == TIM6_SLAVEMODE_GATED) || \ ((MODE) == TIM6_SLAVEMODE_TRIGGER) || \ ((MODE) == TIM6_SLAVEMODE_EXTERNAL1)) /** * @brief Macro TIM6 Flags */ #define IS_TIM6_GET_FLAG_OK(FLAG) \ (((FLAG) == TIM6_FLAG_UPDATE) || \ ((FLAG) == TIM6_FLAG_TRIGGER)) #define IS_TIM6_CLEAR_FLAG_OK(FLAG) \ ((((FLAG) & (uint8_t)0xBE) == 0x00) && ((FLAG) != 0x00)) /** * @brief Macro TIM6 interrupts */ #define IS_TIM6_IT_OK(IT) \ (((IT) != 0x00) && \ (((IT) & (uint8_t)(~(uint8_t)(0x41)))== 0x00)) #define IS_TIM6_GET_IT_OK(IT) \ (((IT) == TIM6_IT_UPDATE) || \ ((IT) == TIM6_IT_TRIGGER)) /** * @brief Macro TIM6 Trigger selection */ #define IS_TIM6_TRIGGER_SELECTION_OK(SELECTION) \ (((SELECTION) == TIM6_TS_TIM5) || \ ((SELECTION) == TIM6_TS_TIM1)) /** * @} */ /* Exported functions --------------------------------------------------------*/ /** @addtogroup TIM6_Exported_Functions * @{ */ void TIM6_DeInit(void); void TIM6_TimeBaseInit(TIM6_Prescaler_TypeDef TIM6_Prescaler, uint8_t TIM6_Period); void TIM6_Cmd(FunctionalState NewState); void TIM6_UpdateDisableConfig(FunctionalState NewState); void TIM6_UpdateRequestConfig(TIM6_UpdateSource_TypeDef TIM6_UpdateSource); void TIM6_SelectOnePulseMode(TIM6_OPMode_TypeDef TIM6_OPMode); void TIM6_PrescalerConfig(TIM6_Prescaler_TypeDef Prescaler, TIM6_PSCReloadMode_TypeDef TIM6_PSCReloadMode); void TIM6_ARRPreloadConfig(FunctionalState NewState); void TIM6_SetCounter(uint8_t Counter); void TIM6_SetAutoreload(uint8_t Autoreload); uint8_t TIM6_GetCounter(void); TIM6_Prescaler_TypeDef TIM6_GetPrescaler(void); void TIM6_ITConfig(TIM6_IT_TypeDef TIM6_IT, FunctionalState NewState); void TIM6_ClearFlag(TIM6_FLAG_TypeDef TIM6_FLAG); ITStatus TIM6_GetITStatus(TIM6_IT_TypeDef TIM6_IT); void TIM6_GenerateEvent(TIM6_EventSource_TypeDef TIM6_EventSource); FlagStatus TIM6_GetFlagStatus(TIM6_FLAG_TypeDef TIM6_FLAG); void TIM6_ClearITPendingBit(TIM6_IT_TypeDef TIM6_IT); void TIM6_SelectOutputTrigger(TIM6_TRGOSource_TypeDef TIM6_TRGOSource); void TIM6_SelectMasterSlaveMode(FunctionalState NewState); void TIM6_SelectInputTrigger(TIM6_TS_TypeDef TIM6_InputTriggerSource); void TIM6_InternalClockConfig(void); void TIM6_SelectSlaveMode(TIM6_SlaveMode_TypeDef TIM6_SlaveMode); /** * @} */ #endif /* __STM8S_TIM6_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_uart1.h ================================================ /** ******************************************************************************** * @file stm8s_uart1.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototypes and macros for the UART1 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_UART1_H #define __STM8S_UART1_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup UART1_Exported_Types * @{ */ /** * @brief UART1 Irda Modes */ typedef enum { UART1_IRDAMODE_NORMAL = (uint8_t)0x00, /**< 0x00 Irda Normal Mode */ UART1_IRDAMODE_LOWPOWER = (uint8_t)0x01 /**< 0x01 Irda Low Power Mode */ } UART1_IrDAMode_TypeDef; /** * @brief UART1 WakeUP Modes */ typedef enum { UART1_WAKEUP_IDLELINE = (uint8_t)0x00, /**< 0x01 Idle Line wake up */ UART1_WAKEUP_ADDRESSMARK = (uint8_t)0x08 /**< 0x02 Address Mark wake up */ } UART1_WakeUp_TypeDef; /** * @brief UART1 LIN Break detection length possible values */ typedef enum { UART1_LINBREAKDETECTIONLENGTH_10BITS = (uint8_t)0x00, /**< 0x01 10 bits Lin Break detection */ UART1_LINBREAKDETECTIONLENGTH_11BITS = (uint8_t)0x01 /**< 0x02 11 bits Lin Break detection */ } UART1_LINBreakDetectionLength_TypeDef; /** * @brief UART1 stop bits possible values */ typedef enum { UART1_STOPBITS_1 = (uint8_t)0x00, /**< One stop bit is transmitted at the end of frame*/ UART1_STOPBITS_0_5 = (uint8_t)0x10, /**< Half stop bits is transmitted at the end of frame*/ UART1_STOPBITS_2 = (uint8_t)0x20, /**< Two stop bits are transmitted at the end of frame*/ UART1_STOPBITS_1_5 = (uint8_t)0x30 /**< One and half stop bits*/ } UART1_StopBits_TypeDef; /** * @brief UART1 parity possible values */ typedef enum { UART1_PARITY_NO = (uint8_t)0x00, /**< No Parity*/ UART1_PARITY_EVEN = (uint8_t)0x04, /**< Even Parity*/ UART1_PARITY_ODD = (uint8_t)0x06 /**< Odd Parity*/ } UART1_Parity_TypeDef; /** * @brief UART1 Synchrone modes */ typedef enum { UART1_SYNCMODE_CLOCK_DISABLE = (uint8_t)0x80, /**< 0x80 Sync mode Disable, SLK pin Disable */ UART1_SYNCMODE_CLOCK_ENABLE = (uint8_t)0x08, /**< 0x08 Sync mode Enable, SLK pin Enable */ UART1_SYNCMODE_CPOL_LOW = (uint8_t)0x40, /**< 0x40 Steady low value on SCLK pin outside transmission window */ UART1_SYNCMODE_CPOL_HIGH = (uint8_t)0x04, /**< 0x04 Steady high value on SCLK pin outside transmission window */ UART1_SYNCMODE_CPHA_MIDDLE = (uint8_t)0x20, /**< 0x20 SCLK clock line activated in middle of data bit */ UART1_SYNCMODE_CPHA_BEGINING = (uint8_t)0x02, /**< 0x02 SCLK clock line activated at beginning of data bit */ UART1_SYNCMODE_LASTBIT_DISABLE = (uint8_t)0x10, /**< 0x10 The clock pulse of the last data bit is not output to the SCLK pin */ UART1_SYNCMODE_LASTBIT_ENABLE = (uint8_t)0x01 /**< 0x01 The clock pulse of the last data bit is output to the SCLK pin */ } UART1_SyncMode_TypeDef; /** * @brief UART1 Word length possible values */ typedef enum { UART1_WORDLENGTH_8D = (uint8_t)0x00,/**< 0x00 8 bits Data */ UART1_WORDLENGTH_9D = (uint8_t)0x10 /**< 0x10 9 bits Data */ } UART1_WordLength_TypeDef; /** * @brief UART1 Mode possible values */ typedef enum { UART1_MODE_RX_ENABLE = (uint8_t)0x08, /**< 0x08 Receive Enable */ UART1_MODE_TX_ENABLE = (uint8_t)0x04, /**< 0x04 Transmit Enable */ UART1_MODE_TX_DISABLE = (uint8_t)0x80, /**< 0x80 Transmit Disable */ UART1_MODE_RX_DISABLE = (uint8_t)0x40, /**< 0x40 Single-wire Half-duplex mode */ UART1_MODE_TXRX_ENABLE = (uint8_t)0x0C /**< 0x0C Transmit Enable and Receive Enable */ } UART1_Mode_TypeDef; /** * @brief UART1 Flag possible values */ typedef enum { UART1_FLAG_TXE = (uint16_t)0x0080, /*!< Transmit Data Register Empty flag */ UART1_FLAG_TC = (uint16_t)0x0040, /*!< Transmission Complete flag */ UART1_FLAG_RXNE = (uint16_t)0x0020, /*!< Read Data Register Not Empty flag */ UART1_FLAG_IDLE = (uint16_t)0x0010, /*!< Idle line detected flag */ UART1_FLAG_OR = (uint16_t)0x0008, /*!< OverRun error flag */ UART1_FLAG_NF = (uint16_t)0x0004, /*!< Noise error flag */ UART1_FLAG_FE = (uint16_t)0x0002, /*!< Framing Error flag */ UART1_FLAG_PE = (uint16_t)0x0001, /*!< Parity Error flag */ UART1_FLAG_LBDF = (uint16_t)0x0210, /*!< Line Break Detection Flag */ UART1_FLAG_SBK = (uint16_t)0x0101 /*!< Send Break characters Flag */ } UART1_Flag_TypeDef; /** * @brief UART1 Interrupt definition * UART1_IT possible values * Elements values convention: 0xZYX * X: Position of the corresponding Interrupt * - For the following values, X means the interrupt position in the CR2 register. * UART1_IT_TXE * UART1_IT_TC * UART1_IT_RXNE * UART1_IT_IDLE * UART1_IT_OR * - For the UART1_IT_PE value, X means the flag position in the CR1 register. * - For the UART1_IT_LBDF value, X means the flag position in the CR4 register. * Y: Flag position * - For the following values, Y means the flag (pending bit) position in the SR register. * UART1_IT_TXE * UART1_IT_TC * UART1_IT_RXNE * UART1_IT_IDLE * UART1_IT_OR * UART1_IT_PE * - For the UART1_IT_LBDF value, Y means the flag position in the CR4 register. * Z: Register index: indicate in which register the dedicated interrupt source is: * - 1==> CR1 register * - 2==> CR2 register * - 3==> CR4 register */ typedef enum { UART1_IT_TXE = (uint16_t)0x0277, /*!< Transmit interrupt */ UART1_IT_TC = (uint16_t)0x0266, /*!< Transmission Complete interrupt */ UART1_IT_RXNE = (uint16_t)0x0255, /*!< Receive interrupt */ UART1_IT_IDLE = (uint16_t)0x0244, /*!< IDLE line interrupt */ UART1_IT_OR = (uint16_t)0x0235, /*!< Overrun Error interrupt */ UART1_IT_PE = (uint16_t)0x0100, /*!< Parity Error interrupt */ UART1_IT_LBDF = (uint16_t)0x0346, /**< LIN break detection interrupt */ UART1_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */ } UART1_IT_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup UART1_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the MODEs possible combination should be one of * the following */ #define IS_UART1_MODE_OK(Mode) \ (((Mode) == (uint8_t)UART1_MODE_RX_ENABLE) || \ ((Mode) == (uint8_t)UART1_MODE_RX_DISABLE) || \ ((Mode) == (uint8_t)UART1_MODE_TX_ENABLE) || \ ((Mode) == (uint8_t)UART1_MODE_TX_DISABLE) || \ ((Mode) == (uint8_t)UART1_MODE_TXRX_ENABLE) || \ ((Mode) == (uint8_t)((uint8_t)UART1_MODE_TX_ENABLE|(uint8_t)UART1_MODE_RX_ENABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART1_MODE_TX_ENABLE|(uint8_t)UART1_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART1_MODE_TX_DISABLE|(uint8_t)UART1_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART1_MODE_TX_DISABLE|(uint8_t)UART1_MODE_RX_ENABLE))) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WordLengths */ #define IS_UART1_WORDLENGTH_OK(WordLength) \ (((WordLength) == UART1_WORDLENGTH_8D) || \ ((WordLength) == UART1_WORDLENGTH_9D)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the SyncModes; it should exclude values such * as UART1_CLOCK_ENABLE|UART1_CLOCK_DISABLE */ #define IS_UART1_SYNCMODE_OK(SyncMode) \ (!((((SyncMode)&(((uint8_t)UART1_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART1_SYNCMODE_CLOCK_DISABLE))) == (((uint8_t)UART1_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART1_SYNCMODE_CLOCK_DISABLE))) \ || (((SyncMode)&(((uint8_t)UART1_SYNCMODE_CPOL_LOW )|((uint8_t)UART1_SYNCMODE_CPOL_HIGH))) == (((uint8_t)UART1_SYNCMODE_CPOL_LOW )|((uint8_t)UART1_SYNCMODE_CPOL_HIGH))) \ ||(((SyncMode)&(((uint8_t)UART1_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART1_SYNCMODE_CPHA_BEGINING))) == (((uint8_t)UART1_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART1_SYNCMODE_CPHA_BEGINING))) \ || (((SyncMode)&(((uint8_t)UART1_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART1_SYNCMODE_LASTBIT_ENABLE))) == (((uint8_t)UART1_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART1_SYNCMODE_LASTBIT_ENABLE))))) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the FLAGs */ #define IS_UART1_FLAG_OK(Flag) \ (((Flag) == UART1_FLAG_TXE) || \ ((Flag) == UART1_FLAG_TC) || \ ((Flag) == UART1_FLAG_RXNE) || \ ((Flag) == UART1_FLAG_IDLE) || \ ((Flag) == UART1_FLAG_OR) || \ ((Flag) == UART1_FLAG_NF) || \ ((Flag) == UART1_FLAG_FE) || \ ((Flag) == UART1_FLAG_PE) || \ ((Flag) == UART1_FLAG_SBK) || \ ((Flag) == UART1_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the FLAGs that can be cleared by writing 0 */ #define IS_UART1_CLEAR_FLAG_OK(Flag) \ (((Flag) == UART1_FLAG_RXNE) || \ ((Flag) == UART1_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the Interrupts */ #define IS_UART1_CONFIG_IT_OK(Interrupt) \ (((Interrupt) == UART1_IT_PE) || \ ((Interrupt) == UART1_IT_TXE) || \ ((Interrupt) == UART1_IT_TC) || \ ((Interrupt) == UART1_IT_RXNE_OR ) || \ ((Interrupt) == UART1_IT_IDLE) || \ ((Interrupt) == UART1_IT_LBDF)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit */ #define IS_UART1_GET_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART1_IT_TXE) || \ ((ITPendingBit) == UART1_IT_TC) || \ ((ITPendingBit) == UART1_IT_RXNE) || \ ((ITPendingBit) == UART1_IT_IDLE) || \ ((ITPendingBit) == UART1_IT_OR) || \ ((ITPendingBit) == UART1_IT_LBDF) || \ ((ITPendingBit) == UART1_IT_PE)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit that can be cleared by writing 0 */ #define IS_UART1_CLEAR_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART1_IT_RXNE) || \ ((ITPendingBit) == UART1_IT_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the IrDAModes */ #define IS_UART1_IRDAMODE_OK(IrDAMode) \ (((IrDAMode) == UART1_IRDAMODE_LOWPOWER) || \ ((IrDAMode) == UART1_IRDAMODE_NORMAL)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WakeUps */ #define IS_UART1_WAKEUP_OK(WakeUp) \ (((WakeUp) == UART1_WAKEUP_IDLELINE) || \ ((WakeUp) == UART1_WAKEUP_ADDRESSMARK)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the LINBreakDetectionLengths */ #define IS_UART1_LINBREAKDETECTIONLENGTH_OK(LINBreakDetectionLength) \ (((LINBreakDetectionLength) == UART1_LINBREAKDETECTIONLENGTH_10BITS) || \ ((LINBreakDetectionLength) == UART1_LINBREAKDETECTIONLENGTH_11BITS)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the UART1_StopBits */ #define IS_UART1_STOPBITS_OK(StopBit) (((StopBit) == UART1_STOPBITS_1) || \ ((StopBit) == UART1_STOPBITS_0_5) || \ ((StopBit) == UART1_STOPBITS_2) || \ ((StopBit) == UART1_STOPBITS_1_5 )) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the Parity */ #define IS_UART1_PARITY_OK(Parity) (((Parity) == UART1_PARITY_NO) || \ ((Parity) == UART1_PARITY_EVEN) || \ ((Parity) == UART1_PARITY_ODD )) /** * @brief Macro used by the assert_param function in order to check the maximum * baudrate value */ #define IS_UART1_BAUDRATE_OK(NUM) ((NUM) <= (uint32_t)625000) /** * @brief Macro used by the assert_param function in order to check the address * of the UART1 or UART node */ #define UART1_ADDRESS_MAX ((uint8_t)16) #define IS_UART1_ADDRESS_OK(node) ((node) < UART1_ADDRESS_MAX ) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup UART1_Exported_Functions * @{ */ void UART1_DeInit(void); void UART1_Init(uint32_t BaudRate, UART1_WordLength_TypeDef WordLength, UART1_StopBits_TypeDef StopBits, UART1_Parity_TypeDef Parity, UART1_SyncMode_TypeDef SyncMode, UART1_Mode_TypeDef Mode); void UART1_Cmd(FunctionalState NewState); void UART1_ITConfig(UART1_IT_TypeDef UART1_IT, FunctionalState NewState); void UART1_HalfDuplexCmd(FunctionalState NewState); void UART1_IrDAConfig(UART1_IrDAMode_TypeDef UART1_IrDAMode); void UART1_IrDACmd(FunctionalState NewState); void UART1_LINBreakDetectionConfig(UART1_LINBreakDetectionLength_TypeDef UART1_LINBreakDetectionLength); void UART1_LINCmd(FunctionalState NewState); void UART1_SmartCardCmd(FunctionalState NewState); void UART1_SmartCardNACKCmd(FunctionalState NewState); void UART1_WakeUpConfig(UART1_WakeUp_TypeDef UART1_WakeUp); void UART1_ReceiverWakeUpCmd(FunctionalState NewState); uint8_t UART1_ReceiveData8(void); uint16_t UART1_ReceiveData9(void); void UART1_SendData8(uint8_t Data); void UART1_SendData9(uint16_t Data); void UART1_SendBreak(void); void UART1_SetAddress(uint8_t UART1_Address); void UART1_SetGuardTime(uint8_t UART1_GuardTime); void UART1_SetPrescaler(uint8_t UART1_Prescaler); FlagStatus UART1_GetFlagStatus(UART1_Flag_TypeDef UART1_FLAG); void UART1_ClearFlag(UART1_Flag_TypeDef UART1_FLAG); ITStatus UART1_GetITStatus(UART1_IT_TypeDef UART1_IT); void UART1_ClearITPendingBit(UART1_IT_TypeDef UART1_IT); /** * @} */ #endif /* __STM8S_UART1_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_uart2.h ================================================ /** ******************************************************************************** * @file stm8s_uart2.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototypes and macros for the UART2 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_UART2_H #define __STM8S_UART2_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup UART2_Exported_Types * @{ */ /** * @brief UART2 Irda Modes */ typedef enum { UART2_IRDAMODE_NORMAL = (uint8_t)0x00, /**< 0x00 Irda Normal Mode */ UART2_IRDAMODE_LOWPOWER = (uint8_t)0x01 /**< 0x01 Irda Low Power Mode */ } UART2_IrDAMode_TypeDef; /** * @brief UART2 WakeUP Modes */ typedef enum { UART2_WAKEUP_IDLELINE = (uint8_t)0x00, /**< 0x01 Idle Line wake up */ UART2_WAKEUP_ADDRESSMARK = (uint8_t)0x08 /**< 0x02 Address Mark wake up */ } UART2_WakeUp_TypeDef; /** * @brief UART2 LIN Break detection length possible values */ typedef enum { UART2_LINBREAKDETECTIONLENGTH_10BITS = (uint8_t)0x00, /**< 0x01 10 bits Lin Break detection */ UART2_LINBREAKDETECTIONLENGTH_11BITS = (uint8_t)0x01 /**< 0x02 11 bits Lin Break detection */ } UART2_LINBreakDetectionLength_TypeDef; /** * @brief UART2 stop bits possible values */ typedef enum { UART2_STOPBITS_1 = (uint8_t)0x00, /**< One stop bit is transmitted at the end of frame*/ UART2_STOPBITS_0_5 = (uint8_t)0x10, /**< Half stop bits is transmitted at the end of frame*/ UART2_STOPBITS_2 = (uint8_t)0x20, /**< Two stop bits are transmitted at the end of frame*/ UART2_STOPBITS_1_5 = (uint8_t)0x30 /**< One and half stop bits*/ } UART2_StopBits_TypeDef; /** * @brief UART2 parity possible values */ typedef enum { UART2_PARITY_NO = (uint8_t)0x00, /**< No Parity*/ UART2_PARITY_EVEN = (uint8_t)0x04, /**< Even Parity*/ UART2_PARITY_ODD = (uint8_t)0x06 /**< Odd Parity*/ } UART2_Parity_TypeDef; /** * @brief UART2 Mode possible values */ typedef enum { UART2_LIN_MODE_MASTER = (uint8_t)0x00, /**< LIN Master Mode*/ UART2_LIN_MODE_SLAVE = (uint8_t)0x01 /**< LIN Slave Mode*/ } UART2_LinMode_TypeDef; /** * @brief UART2 automatic resynchronisation possible values */ typedef enum { UART2_LIN_AUTOSYNC_DISABLE = (uint8_t)0x00, /**< LIN Autosynchronization Disable*/ UART2_LIN_AUTOSYNC_ENABLE = (uint8_t)0x01 /**< LIN Autosynchronization Enable*/ } UART2_LinAutosync_TypeDef; /** * @brief UART2 Divider Update Method possible values */ typedef enum { UART2_LIN_DIVUP_LBRR1 = (uint8_t)0x00, /**< LIN LDIV is updated as soon as LBRR1 is written*/ UART2_LIN_DIVUP_NEXTRXNE = (uint8_t)0x01 /**< LIN LDIV is updated at the next received character*/ } UART2_LinDivUp_TypeDef; /** * @brief UART2 Synchrone modes */ typedef enum { UART2_SYNCMODE_CLOCK_DISABLE = (uint8_t)0x80, /**< 0x80 Sync mode Disable, SLK pin Disable */ UART2_SYNCMODE_CLOCK_ENABLE = (uint8_t)0x08, /**< 0x08 Sync mode Enable, SLK pin Enable */ UART2_SYNCMODE_CPOL_LOW = (uint8_t)0x40, /**< 0x40 Steady low value on SCLK pin outside transmission window */ UART2_SYNCMODE_CPOL_HIGH = (uint8_t)0x04, /**< 0x04 Steady high value on SCLK pin outside transmission window */ UART2_SYNCMODE_CPHA_MIDDLE = (uint8_t)0x20, /**< 0x20 SCLK clock line activated in middle of data bit */ UART2_SYNCMODE_CPHA_BEGINING = (uint8_t)0x02, /**< 0x02 SCLK clock line activated at beginning of data bit */ UART2_SYNCMODE_LASTBIT_DISABLE = (uint8_t)0x10, /**< 0x10 The clock pulse of the last data bit is not output to the SCLK pin */ UART2_SYNCMODE_LASTBIT_ENABLE = (uint8_t)0x01 /**< 0x01 The clock pulse of the last data bit is output to the SCLK pin */ } UART2_SyncMode_TypeDef; /** * @brief UART2 Word length possible values */ typedef enum { UART2_WORDLENGTH_8D = (uint8_t)0x00,/**< 0x00 8 bits Data */ UART2_WORDLENGTH_9D = (uint8_t)0x10 /**< 0x10 9 bits Data */ } UART2_WordLength_TypeDef; /** * @brief UART2 Mode possible values */ typedef enum { UART2_MODE_RX_ENABLE = (uint8_t)0x08, /**< 0x08 Receive Enable */ UART2_MODE_TX_ENABLE = (uint8_t)0x04, /**< 0x04 Transmit Enable */ UART2_MODE_TX_DISABLE = (uint8_t)0x80, /**< 0x80 Transmit Disable */ UART2_MODE_RX_DISABLE = (uint8_t)0x40, /**< 0x40 Single-wire Half-duplex mode */ UART2_MODE_TXRX_ENABLE = (uint8_t)0x0C /**< 0x0C Transmit Enable and Receive Enable */ } UART2_Mode_TypeDef; /** * @brief UART2 Flag possible values */ typedef enum { UART2_FLAG_TXE = (uint16_t)0x0080, /*!< Transmit Data Register Empty flag */ UART2_FLAG_TC = (uint16_t)0x0040, /*!< Transmission Complete flag */ UART2_FLAG_RXNE = (uint16_t)0x0020, /*!< Read Data Register Not Empty flag */ UART2_FLAG_IDLE = (uint16_t)0x0010, /*!< Idle line detected flag */ UART2_FLAG_OR_LHE = (uint16_t)0x0008, /*!< OverRun error flag */ UART2_FLAG_NF = (uint16_t)0x0004, /*!< Noise error flag */ UART2_FLAG_FE = (uint16_t)0x0002, /*!< Framing Error flag */ UART2_FLAG_PE = (uint16_t)0x0001, /*!< Parity Error flag */ UART2_FLAG_SBK = (uint16_t)0x0101, /**< Send Break Complete interrupt flag */ UART2_FLAG_LBDF = (uint16_t)0x0210, /**< LIN Break Detection Flag */ UART2_FLAG_LHDF = (uint16_t)0x0302, /**< LIN Header Detection Flag*/ UART2_FLAG_LSF = (uint16_t)0x0301 /**< LIN Sync Field Flag*/ } UART2_Flag_TypeDef; /** * @brief UART2 Interrupt definition * UART2_IT possible values * Elements values convention: 0xZYX * X: Position of the corresponding Interrupt * - For the following values, X means the interrupt position in the CR2 register. * UART2_IT_TXE * UART2_IT_TC * UART2_IT_RXNE * UART2_IT_IDLE * UART2_IT_OR * - For the UART2_IT_PE value, X means the flag position in the CR1 register. * - For the UART2_IT_LBDF value, X means the flag position in the CR4 register. * - For the UART2_IT_LHDF value, X means the flag position in the CR6 register. * Y: Flag position * - For the following values, Y means the flag (pending bit) position in the SR register. * UART2_IT_TXE * UART2_IT_TC * UART2_IT_RXNE * UART2_IT_IDLE * UART2_IT_OR * UART2_IT_PE * - For the UART2_IT_LBDF value, Y means the flag position in the CR4 register. * - For the UART2_IT_LHDF value, Y means the flag position in the CR6 register. * Z: Register index: indicate in which register the dedicated interrupt source is: * - 1==> CR1 register * - 2==> CR2 register * - 3==> CR4 register * - 4==> CR6 register */ typedef enum { UART2_IT_TXE = (uint16_t)0x0277, /**< Transmit interrupt */ UART2_IT_TC = (uint16_t)0x0266, /**< Transmission Complete interrupt */ UART2_IT_RXNE = (uint16_t)0x0255, /**< Data Register Not Empty interrupt */ UART2_IT_IDLE = (uint16_t)0x0244, /**< Idle line detected interrupt */ UART2_IT_OR = (uint16_t)0x0235, /**< OverRun error interrupt */ UART2_IT_PE = (uint16_t)0x0100, /**< Parity Error interrupt */ UART2_IT_LBDF = (uint16_t)0x0346, /**< LIN Break Detection interrupt */ UART2_IT_LHDF = (uint16_t)0x0412, /**< LIN Header Detection interrupt*/ UART2_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */ } UART2_IT_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup UART2_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the MODEs possible combination should be one of * the following. */ #define IS_UART2_MODE_OK(Mode) \ (((Mode) == (uint8_t)UART2_MODE_RX_ENABLE) || \ ((Mode) == (uint8_t)UART2_MODE_RX_DISABLE) || \ ((Mode) == (uint8_t)UART2_MODE_TX_ENABLE) || \ ((Mode) == (uint8_t)UART2_MODE_TX_DISABLE) || \ ((Mode) == (uint8_t)UART2_MODE_TXRX_ENABLE) || \ ((Mode) == (uint8_t)((uint8_t)UART2_MODE_TX_ENABLE|(uint8_t)UART2_MODE_RX_ENABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART2_MODE_TX_ENABLE|(uint8_t)UART2_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART2_MODE_TX_DISABLE|(uint8_t)UART2_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART2_MODE_TX_DISABLE|(uint8_t)UART2_MODE_RX_ENABLE))) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WordLengths */ #define IS_UART2_WORDLENGTH_OK(WordLength) \ (((WordLength) == UART2_WORDLENGTH_8D) || \ ((WordLength) == UART2_WORDLENGTH_9D)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the SyncModes; it should exclude values such * as UART2_CLOCK_ENABLE|UART2_CLOCK_DISABLE */ #define IS_UART2_SYNCMODE_OK(SyncMode) \ (!((((SyncMode)&(((uint8_t)UART2_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART2_SYNCMODE_CLOCK_DISABLE))) == (((uint8_t)UART2_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART2_SYNCMODE_CLOCK_DISABLE))) || \ (((SyncMode)&(((uint8_t)UART2_SYNCMODE_CPOL_LOW )|((uint8_t)UART2_SYNCMODE_CPOL_HIGH))) == (((uint8_t)UART2_SYNCMODE_CPOL_LOW )|((uint8_t)UART2_SYNCMODE_CPOL_HIGH))) || \ (((SyncMode)&(((uint8_t)UART2_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART2_SYNCMODE_CPHA_BEGINING))) == (((uint8_t)UART2_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART2_SYNCMODE_CPHA_BEGINING))) || \ (((SyncMode)&(((uint8_t)UART2_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART2_SYNCMODE_LASTBIT_ENABLE))) == (((uint8_t)UART2_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART2_SYNCMODE_LASTBIT_ENABLE))))) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs */ #define IS_UART2_FLAG_OK(Flag) \ (((Flag) == UART2_FLAG_TXE) || \ ((Flag) == UART2_FLAG_TC) || \ ((Flag) == UART2_FLAG_RXNE) || \ ((Flag) == UART2_FLAG_IDLE) || \ ((Flag) == UART2_FLAG_OR_LHE) || \ ((Flag) == UART2_FLAG_NF) || \ ((Flag) == UART2_FLAG_FE) || \ ((Flag) == UART2_FLAG_PE) || \ ((Flag) == UART2_FLAG_SBK) || \ ((Flag) == UART2_FLAG_LSF) || \ ((Flag) == UART2_FLAG_LHDF) || \ ((Flag) == UART2_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs that can be cleared by writing 0 */ #define IS_UART2_CLEAR_FLAG_OK(Flag) \ (((Flag) == UART2_FLAG_RXNE) || \ ((Flag) == UART2_FLAG_LHDF) || \ ((Flag) == UART2_FLAG_LSF) || \ ((Flag) == UART2_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check * the different sensitivity values for the Interrupts */ #define IS_UART2_CONFIG_IT_OK(Interrupt) \ (((Interrupt) == UART2_IT_PE) || \ ((Interrupt) == UART2_IT_TXE) || \ ((Interrupt) == UART2_IT_TC) || \ ((Interrupt) == UART2_IT_RXNE_OR ) || \ ((Interrupt) == UART2_IT_IDLE) || \ ((Interrupt) == UART2_IT_LHDF) || \ ((Interrupt) == UART2_IT_LBDF)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit */ #define IS_UART2_GET_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART2_IT_TXE) || \ ((ITPendingBit) == UART2_IT_TC) || \ ((ITPendingBit) == UART2_IT_RXNE) || \ ((ITPendingBit) == UART2_IT_IDLE) || \ ((ITPendingBit) == UART2_IT_OR) || \ ((ITPendingBit) == UART2_IT_LBDF) || \ ((ITPendingBit) == UART2_IT_LHDF) || \ ((ITPendingBit) == UART2_IT_PE)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit that can be cleared by writing 0 */ #define IS_UART2_CLEAR_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART2_IT_RXNE) || \ ((ITPendingBit) == UART2_IT_LHDF) || \ ((ITPendingBit) == UART2_IT_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the IrDAModes */ #define IS_UART2_IRDAMODE_OK(IrDAMode) \ (((IrDAMode) == UART2_IRDAMODE_LOWPOWER) || \ ((IrDAMode) == UART2_IRDAMODE_NORMAL)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WakeUps */ #define IS_UART2_WAKEUP_OK(WakeUp) \ (((WakeUp) == UART2_WAKEUP_IDLELINE) || \ ((WakeUp) == UART2_WAKEUP_ADDRESSMARK)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the LINBreakDetectionLengths */ #define IS_UART2_LINBREAKDETECTIONLENGTH_OK(LINBreakDetectionLength) \ (((LINBreakDetectionLength) == UART2_LINBREAKDETECTIONLENGTH_10BITS) || \ ((LINBreakDetectionLength) == UART2_LINBREAKDETECTIONLENGTH_11BITS)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the UART2_StopBits */ #define IS_UART2_STOPBITS_OK(StopBit) (((StopBit) == UART2_STOPBITS_1) || \ ((StopBit) == UART2_STOPBITS_0_5) || \ ((StopBit) == UART2_STOPBITS_2) || \ ((StopBit) == UART2_STOPBITS_1_5 )) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the Paritys */ #define IS_UART2_PARITY_OK(Parity) (((Parity) == UART2_PARITY_NO) || \ ((Parity) == UART2_PARITY_EVEN) || \ ((Parity) == UART2_PARITY_ODD )) /** * @brief Macro used by the assert_param function in order to check the maximum * baudrate value */ #define IS_UART2_BAUDRATE_OK(NUM) ((NUM) <= (uint32_t)625000) /** * @brief Macro used by the assert_param function in order to check the address * of the UART2 or UART node */ #define UART2_ADDRESS_MAX ((uint8_t)16) #define IS_UART2_ADDRESS_OK(node) ((node) < UART2_ADDRESS_MAX ) /** * @brief Macro used by the assert_param function in order to check the LIN mode */ #define IS_UART2_SLAVE_OK(Mode) \ (((Mode) == UART2_LIN_MODE_MASTER) || \ ((Mode) == UART2_LIN_MODE_SLAVE)) /** * @brief Macro used by the assert_param function in order to check the LIN * automatic resynchronization mode */ #define IS_UART2_AUTOSYNC_OK(AutosyncMode) \ (((AutosyncMode) == UART2_LIN_AUTOSYNC_ENABLE) || \ ((AutosyncMode) == UART2_LIN_AUTOSYNC_DISABLE)) /** * @brief Macro used by the assert_param function in order to check the LIN divider update method */ #define IS_UART2_DIVUP_OK(DivupMethod) \ (((DivupMethod) == UART2_LIN_DIVUP_LBRR1) || \ ((DivupMethod) == UART2_LIN_DIVUP_NEXTRXNE)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup UART2_Exported_Functions * @{ */ void UART2_DeInit(void); void UART2_Init(uint32_t BaudRate, UART2_WordLength_TypeDef WordLength, UART2_StopBits_TypeDef StopBits, UART2_Parity_TypeDef Parity, UART2_SyncMode_TypeDef SyncMode, UART2_Mode_TypeDef Mode); void UART2_Cmd(FunctionalState NewState); void UART2_ITConfig(UART2_IT_TypeDef UART2_IT, FunctionalState NewState); void UART2_HalfDuplexCmd(FunctionalState NewState); void UART2_IrDAConfig(UART2_IrDAMode_TypeDef UART2_IrDAMode); void UART2_IrDACmd(FunctionalState NewState); void UART2_LINBreakDetectionConfig(UART2_LINBreakDetectionLength_TypeDef UART2_LINBreakDetectionLength); void UART2_LINConfig(UART2_LinMode_TypeDef UART2_Mode, UART2_LinAutosync_TypeDef UART2_Autosync, UART2_LinDivUp_TypeDef UART2_DivUp); void UART2_LINCmd(FunctionalState NewState); void UART2_SmartCardCmd(FunctionalState NewState); void UART2_SmartCardNACKCmd(FunctionalState NewState); void UART2_WakeUpConfig(UART2_WakeUp_TypeDef UART2_WakeUp); void UART2_ReceiverWakeUpCmd(FunctionalState NewState); uint8_t UART2_ReceiveData8(void); uint16_t UART2_ReceiveData9(void); void UART2_SendData8(uint8_t Data); void UART2_SendData9(uint16_t Data); void UART2_SendBreak(void); void UART2_SetAddress(uint8_t UART2_Address); void UART2_SetGuardTime(uint8_t UART2_GuardTime); void UART2_SetPrescaler(uint8_t UART2_Prescaler); FlagStatus UART2_GetFlagStatus(UART2_Flag_TypeDef UART2_FLAG); void UART2_ClearFlag(UART2_Flag_TypeDef UART2_FLAG); ITStatus UART2_GetITStatus(UART2_IT_TypeDef UART2_IT); void UART2_ClearITPendingBit(UART2_IT_TypeDef UART2_IT); /** * @} */ #endif /* __STM8S_UART2_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_uart3.h ================================================ /** ******************************************************************************** * @file stm8s_uart3.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototypes and macros for the UART3 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_UART3_H #define __STM8S_UART3_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup UART3_Exported_Types * @{ */ /** * @brief UART3 WakeUP Modes */ typedef enum { UART3_WAKEUP_IDLELINE = (uint8_t)0x00, /**< 0x01 Idle Line wake up*/ UART3_WAKEUP_ADDRESSMARK = (uint8_t)0x08 /**< 0x02 Address Mark wake up*/ } UART3_WakeUp_TypeDef; /** * @brief UART3 LIN Break detection length possible values */ typedef enum { UART3_LINBREAKDETECTIONLENGTH_10BITS = (uint8_t)0x00, /**< 10 bits Lin Break detection */ UART3_LINBREAKDETECTIONLENGTH_11BITS = (uint8_t)0x01 /**< 11 bits Lin Break detection */ } UART3_LINBreakDetectionLength_TypeDef; /** * @brief UART3 stop bits possible values */ typedef enum { UART3_STOPBITS_1 = (uint8_t)0x00, /**< One stop bit is transmitted at the end of frame*/ UART3_STOPBITS_2 = (uint8_t)0x20 /**< Two stop bits are transmitted at the end of frame*/ } UART3_StopBits_TypeDef; /** * @brief UART3 parity possible values */ typedef enum { UART3_PARITY_NO = (uint8_t)0x00, /**< No Parity*/ UART3_PARITY_EVEN = (uint8_t)0x04, /**< Even Parity*/ UART3_PARITY_ODD = (uint8_t)0x06 /**< Odd Parity*/ } UART3_Parity_TypeDef; /** * @brief UART3 Word length possible values */ typedef enum { UART3_WORDLENGTH_8D = (uint8_t)0x00, /**< 0x00 8 bits Data*/ UART3_WORDLENGTH_9D = (uint8_t)0x10 /**< 0x10 9 bits Data*/ } UART3_WordLength_TypeDef; /** * @brief UART3 Mode Transmit/Receive possible values */ typedef enum { UART3_MODE_RX_ENABLE = (uint8_t)0x08, /**< 0x08 Receive Enable*/ UART3_MODE_TX_ENABLE = (uint8_t)0x04, /**< 0x04 Transmit Enable*/ UART3_MODE_TX_DISABLE = (uint8_t)0x80, /**< 0x80 Receive Enable*/ UART3_MODE_RX_DISABLE = (uint8_t)0x40, /**< 0x40 Single-wire Half-duplex mode*/ UART3_MODE_TXRX_ENABLE = (uint8_t)0x0C /**< 0x0C Receive Enable and Transmit enable*/ } UART3_Mode_TypeDef; /** * @brief UART3 Mode possible values */ typedef enum { UART3_LIN_MODE_MASTER = (uint8_t)0x00, /**< LIN Master Mode*/ UART3_LIN_MODE_SLAVE = (uint8_t)0x01 /**< LIN Slave Mode*/ } UART3_LinMode_TypeDef; /** * @brief UART3 automatic resynchronisation possible values */ typedef enum { UART3_LIN_AUTOSYNC_DISABLE = (uint8_t)0x00, /**< LIN Autosynchronization Disable*/ UART3_LIN_AUTOSYNC_ENABLE = (uint8_t)0x01 /**< LIN Autosynchronization Enable*/ } UART3_LinAutosync_TypeDef; /** * @brief UART3 Divider Update Method possible values */ typedef enum { UART3_LIN_DIVUP_LBRR1 = (uint8_t)0x00, /**< LIN LDIV is updated as soon as LBRR1 is written*/ UART3_LIN_DIVUP_NEXTRXNE = (uint8_t)0x01 /**< LIN LDIV is updated at the next received character*/ } UART3_LinDivUp_TypeDef; /** * @brief UART3 Flag possible values */ typedef enum { UART3_FLAG_TXE = (uint16_t)0x0080, /*!< Transmit Data Register Empty flag */ UART3_FLAG_TC = (uint16_t)0x0040, /*!< Transmission Complete flag */ UART3_FLAG_RXNE = (uint16_t)0x0020, /*!< Read Data Register Not Empty flag */ UART3_FLAG_IDLE = (uint16_t)0x0010, /*!< Idle line detected flag */ UART3_FLAG_OR_LHE = (uint16_t)0x0008, /*!< OverRun error flag */ UART3_FLAG_NF = (uint16_t)0x0004, /*!< Noise error flag */ UART3_FLAG_FE = (uint16_t)0x0002, /*!< Framing Error flag */ UART3_FLAG_PE = (uint16_t)0x0001, /*!< Parity Error flag */ UART3_FLAG_SBK = (uint16_t)0x0101, /**< Send Break Complete interrupt flag */ UART3_FLAG_LBDF = (uint16_t)0x0210, /**< LIN Break Detection Flag */ UART3_FLAG_LHDF = (uint16_t)0x0302, /**< LIN Header Detection Flag*/ UART3_FLAG_LSF = (uint16_t)0x0301 /**< LIN Sync Field Flag*/ } UART3_Flag_TypeDef; /** * @brief UART3 Interrupt definition * UART3_IT possible values * Elements values convention: 0xZYX * X: Position of the corresponding Interrupt * - For the following values, X means the interrupt position in the CR2 register. * UART3_IT_TXE * UART3_IT_TC * UART3_IT_RXNE * UART3_IT_IDLE * UART3_IT_OR * - For the UART3_IT_PE value, X means the flag position in the CR1 register. * - For the UART3_IT_LBDF value, X means the flag position in the CR4 register. * - For the UART3_IT_LHDF value, X means the flag position in the CR6 register. * Y: Flag position * - For the following values, Y means the flag (pending bit) position in the SR register. * UART3_IT_TXE * UART3_IT_TC * UART3_IT_RXNE * UART3_IT_IDLE * UART3_IT_OR * UART3_IT_PE * - For the UART3_IT_LBDF value, Y means the flag position in the CR4 register. * - For the UART3_IT_LHDF value, Y means the flag position in the CR6 register. * Z: Register index: indicate in which register the dedicated interrupt source is: * - 1==> CR1 register * - 2==> CR2 register * - 3==> CR4 register * - 4==> CR6 register */ typedef enum { UART3_IT_TXE = (uint16_t)0x0277, /**< Transmit interrupt */ UART3_IT_TC = (uint16_t)0x0266, /**< Transmission Complete interrupt */ UART3_IT_RXNE = (uint16_t)0x0255, /**< Data Register Not Empty interrupt */ UART3_IT_IDLE = (uint16_t)0x0244, /**< Idle line detected interrupt */ UART3_IT_OR = (uint16_t)0x0235, /**< OverRun error interrupt */ UART3_IT_PE = (uint16_t)0x0100, /**< Parity Error interrupt */ UART3_IT_LBDF = (uint16_t)0x0346, /**< LIN Break Detection interrupt */ UART3_IT_LHDF = (uint16_t)0x0412, /**< LIN Header Detection interrupt*/ UART3_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */ } UART3_IT_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros ------------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup UART3_Private_Macros * @{ */ /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs */ #define IS_UART3_FLAG_OK(Flag) \ (((Flag) == UART3_FLAG_TXE) || \ ((Flag) == UART3_FLAG_TC) || \ ((Flag) == UART3_FLAG_RXNE) || \ ((Flag) == UART3_FLAG_IDLE) || \ ((Flag) == UART3_FLAG_OR_LHE) || \ ((Flag) == UART3_FLAG_NF) || \ ((Flag) == UART3_FLAG_FE) || \ ((Flag) == UART3_FLAG_PE) || \ ((Flag) == UART3_FLAG_SBK) || \ ((Flag) == UART3_FLAG_LSF) || \ ((Flag) == UART3_FLAG_LHDF) || \ ((Flag) == UART3_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs that can be cleared by writing 0 */ #define IS_UART3_CLEAR_FLAG_OK(Flag) \ (((Flag) == UART3_FLAG_RXNE) || \ ((Flag) == UART3_FLAG_LHDF) || \ ((Flag) == UART3_FLAG_LSF) || \ ((Flag) == UART3_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the Interrupts */ #define IS_UART3_CONFIG_IT_OK(Interrupt) \ (((Interrupt) == UART3_IT_PE) || \ ((Interrupt) == UART3_IT_TXE) || \ ((Interrupt) == UART3_IT_TC) || \ ((Interrupt) == UART3_IT_RXNE_OR ) || \ ((Interrupt) == UART3_IT_IDLE) || \ ((Interrupt) == UART3_IT_LHDF) || \ ((Interrupt) == UART3_IT_LBDF)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit */ #define IS_UART3_GET_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART3_IT_TXE) || \ ((ITPendingBit) == UART3_IT_TC) || \ ((ITPendingBit) == UART3_IT_RXNE) || \ ((ITPendingBit) == UART3_IT_IDLE) || \ ((ITPendingBit) == UART3_IT_OR) || \ ((ITPendingBit) == UART3_IT_LBDF) || \ ((ITPendingBit) == UART3_IT_LHDF) || \ ((ITPendingBit) == UART3_IT_PE)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit that can be cleared by writing 0 */ #define IS_UART3_CLEAR_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART3_IT_RXNE) || \ ((ITPendingBit) == UART3_IT_LHDF) || \ ((ITPendingBit) == UART3_IT_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the MODEs */ #define IS_UART3_MODE_OK(Mode) \ (((Mode) == (uint8_t)UART3_MODE_RX_ENABLE) || \ ((Mode) == (uint8_t)UART3_MODE_RX_DISABLE) || \ ((Mode) == (uint8_t)UART3_MODE_TX_ENABLE) || \ ((Mode) == (uint8_t)UART3_MODE_TX_DISABLE) || \ ((Mode) == (uint8_t)UART3_MODE_TXRX_ENABLE) || \ ((Mode) == (uint8_t)((uint8_t)UART3_MODE_TX_ENABLE|(uint8_t)UART3_MODE_RX_ENABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART3_MODE_TX_ENABLE|(uint8_t)UART3_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART3_MODE_TX_DISABLE|(uint8_t)UART3_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART3_MODE_TX_DISABLE|(uint8_t)UART3_MODE_RX_ENABLE))) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WordLengths */ #define IS_UART3_WORDLENGTH_OK(WordLength) \ (((WordLength) == UART3_WORDLENGTH_8D) || \ ((WordLength) == UART3_WORDLENGTH_9D)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WakeUps */ #define IS_UART3_WAKEUP_OK(WakeUpMode) \ (((WakeUpMode) == UART3_WAKEUP_IDLELINE) || \ ((WakeUpMode) == UART3_WAKEUP_ADDRESSMARK)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the LINBreakDetectionLengths */ #define IS_UART3_LINBREAKDETECTIONLENGTH_OK(LINBreakDetectionLengths) \ (((LINBreakDetectionLengths) == UART3_LINBREAKDETECTIONLENGTH_10BITS) || \ ((LINBreakDetectionLengths) == UART3_LINBREAKDETECTIONLENGTH_11BITS)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the UART3_StopBits */ #define IS_UART3_STOPBITS_OK(StopBit) \ (((StopBit) == UART3_STOPBITS_1) || \ ((StopBit) == UART3_STOPBITS_2)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the Parity */ #define IS_UART3_PARITY_OK(Parity) \ (((Parity) == UART3_PARITY_NO) || \ ((Parity) == UART3_PARITY_EVEN) || \ ((Parity) == UART3_PARITY_ODD )) /** * @brief Macro used by the assert_param function in order to check the maximum * baudrate value */ #define IS_UART3_BAUDRATE_OK(NUM) ((NUM) <= (uint32_t)625000) /** * @brief Macro used by the assert_param function in order to check the address * of the UART3 or UART node */ #define UART3_ADDRESS_MAX ((uint8_t)16) #define IS_UART3_ADDRESS_OK(Node) ((Node) < UART3_ADDRESS_MAX) /** * @brief Macro used by the assert_param function in order to check the LIN mode */ #define IS_UART3_SLAVE_OK(Mode) \ (((Mode) == UART3_LIN_MODE_MASTER) || \ ((Mode) == UART3_LIN_MODE_SLAVE)) /** * @brief Macro used by the assert_param function in order to check the LIN * automatic resynchronization mode */ #define IS_UART3_AUTOSYNC_OK(AutosyncMode) \ (((AutosyncMode) == UART3_LIN_AUTOSYNC_ENABLE) || \ ((AutosyncMode) == UART3_LIN_AUTOSYNC_DISABLE)) /** * @brief Macro used by the assert_param function in order to check the LIN * divider update method */ #define IS_UART3_DIVUP_OK(DivupMethod) \ (((DivupMethod) == UART3_LIN_DIVUP_LBRR1) || \ ((DivupMethod) == UART3_LIN_DIVUP_NEXTRXNE)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup UART3_Exported_Functions * @{ */ void UART3_DeInit(void); void UART3_Init(uint32_t BaudRate, UART3_WordLength_TypeDef WordLength, UART3_StopBits_TypeDef StopBits, UART3_Parity_TypeDef Parity, UART3_Mode_TypeDef Mode); void UART3_Cmd(FunctionalState NewState); void UART3_ITConfig(UART3_IT_TypeDef UART3_IT, FunctionalState NewState); void UART3_LINBreakDetectionConfig(UART3_LINBreakDetectionLength_TypeDef UART3_LINBreakDetectionLength); void UART3_LINConfig(UART3_LinMode_TypeDef UART3_Mode, UART3_LinAutosync_TypeDef UART3_Autosync, UART3_LinDivUp_TypeDef UART3_DivUp); void UART3_LINCmd(FunctionalState NewState); void UART3_ReceiverWakeUpCmd(FunctionalState NewState); void UART3_WakeUpConfig( UART3_WakeUp_TypeDef UART3_WakeUp); uint8_t UART3_ReceiveData8(void); uint16_t UART3_ReceiveData9(void); void UART3_SendData8(uint8_t Data); void UART3_SendData9(uint16_t Data); void UART3_SendBreak(void); void UART3_SetAddress(uint8_t UART3_Address); FlagStatus UART3_GetFlagStatus(UART3_Flag_TypeDef UART3_FLAG); void UART3_ClearFlag(UART3_Flag_TypeDef UART3_FLAG); ITStatus UART3_GetITStatus(UART3_IT_TypeDef UART3_IT); void UART3_ClearITPendingBit(UART3_IT_TypeDef UART3_IT); /** * @} */ #endif /* __STM8S_UART3_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_uart4.h ================================================ /** ******************************************************************************** * @file stm8s_uart4.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototypes and macros for the UART4 peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_UART4_H #define __STM8S_UART4_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Exported types ------------------------------------------------------------*/ /** @addtogroup UART4_Exported_Types * @{ */ /** * @brief UART4 Irda Modes */ typedef enum { UART4_IRDAMODE_NORMAL = (uint8_t)0x00, /**< 0x00 Irda Normal Mode */ UART4_IRDAMODE_LOWPOWER = (uint8_t)0x01 /**< 0x01 Irda Low Power Mode */ } UART4_IrDAMode_TypeDef; /** * @brief UART4 WakeUP Modes */ typedef enum { UART4_WAKEUP_IDLELINE = (uint8_t)0x00, /**< 0x01 Idle Line wake up */ UART4_WAKEUP_ADDRESSMARK = (uint8_t)0x08 /**< 0x02 Address Mark wake up */ } UART4_WakeUp_TypeDef; /** * @brief UART4 LIN Break detection length possible values */ typedef enum { UART4_LINBREAKDETECTIONLENGTH_10BITS = (uint8_t)0x00, /**< 0x01 10 bits Lin Break detection */ UART4_LINBREAKDETECTIONLENGTH_11BITS = (uint8_t)0x01 /**< 0x02 11 bits Lin Break detection */ } UART4_LINBreakDetectionLength_TypeDef; /** * @brief UART4 stop bits possible values */ typedef enum { UART4_STOPBITS_1 = (uint8_t)0x00, /**< One stop bit is transmitted at the end of frame*/ UART4_STOPBITS_0_5 = (uint8_t)0x10, /**< Half stop bits is transmitted at the end of frame*/ UART4_STOPBITS_2 = (uint8_t)0x20, /**< Two stop bits are transmitted at the end of frame*/ UART4_STOPBITS_1_5 = (uint8_t)0x30 /**< One and half stop bits*/ } UART4_StopBits_TypeDef; /** * @brief UART4 parity possible values */ typedef enum { UART4_PARITY_NO = (uint8_t)0x00, /**< No Parity*/ UART4_PARITY_EVEN = (uint8_t)0x04, /**< Even Parity*/ UART4_PARITY_ODD = (uint8_t)0x06 /**< Odd Parity*/ } UART4_Parity_TypeDef; /** * @brief UART4 Mode possible values */ typedef enum { UART4_LIN_MODE_MASTER = (uint8_t)0x00, /**< LIN Master Mode*/ UART4_LIN_MODE_SLAVE = (uint8_t)0x01 /**< LIN Slave Mode*/ } UART4_LinMode_TypeDef; /** * @brief UART4 automatic resynchronisation possible values */ typedef enum { UART4_LIN_AUTOSYNC_DISABLE = (uint8_t)0x00, /**< LIN Autosynchronization Disable*/ UART4_LIN_AUTOSYNC_ENABLE = (uint8_t)0x01 /**< LIN Autosynchronization Enable*/ } UART4_LinAutosync_TypeDef; /** * @brief UART4 Divider Update Method possible values */ typedef enum { UART4_LIN_DIVUP_LBRR1 = (uint8_t)0x00, /**< LIN LDIV is updated as soon as LBRR1 is written*/ UART4_LIN_DIVUP_NEXTRXNE = (uint8_t)0x01 /**< LIN LDIV is updated at the next received character*/ } UART4_LinDivUp_TypeDef; /** * @brief UART4 Synchrone modes */ typedef enum { UART4_SYNCMODE_CLOCK_DISABLE = (uint8_t)0x80, /**< 0x80 Sync mode Disable, SLK pin Disable */ UART4_SYNCMODE_CLOCK_ENABLE = (uint8_t)0x08, /**< 0x08 Sync mode Enable, SLK pin Enable */ UART4_SYNCMODE_CPOL_LOW = (uint8_t)0x40, /**< 0x40 Steady low value on SCLK pin outside transmission window */ UART4_SYNCMODE_CPOL_HIGH = (uint8_t)0x04, /**< 0x04 Steady high value on SCLK pin outside transmission window */ UART4_SYNCMODE_CPHA_MIDDLE = (uint8_t)0x20, /**< 0x20 SCLK clock line activated in middle of data bit */ UART4_SYNCMODE_CPHA_BEGINING = (uint8_t)0x02, /**< 0x02 SCLK clock line activated at beginning of data bit */ UART4_SYNCMODE_LASTBIT_DISABLE = (uint8_t)0x10, /**< 0x10 The clock pulse of the last data bit is not output to the SCLK pin */ UART4_SYNCMODE_LASTBIT_ENABLE = (uint8_t)0x01 /**< 0x01 The clock pulse of the last data bit is output to the SCLK pin */ } UART4_SyncMode_TypeDef; /** * @brief UART4 Word length possible values */ typedef enum { UART4_WORDLENGTH_8D = (uint8_t)0x00,/**< 0x00 8 bits Data */ UART4_WORDLENGTH_9D = (uint8_t)0x10 /**< 0x10 9 bits Data */ } UART4_WordLength_TypeDef; /** * @brief UART4 Mode possible values */ typedef enum { UART4_MODE_RX_ENABLE = (uint8_t)0x08, /**< 0x08 Receive Enable */ UART4_MODE_TX_ENABLE = (uint8_t)0x04, /**< 0x04 Transmit Enable */ UART4_MODE_TX_DISABLE = (uint8_t)0x80, /**< 0x80 Transmit Disable */ UART4_MODE_RX_DISABLE = (uint8_t)0x40, /**< 0x40 Single-wire Half-duplex mode */ UART4_MODE_TXRX_ENABLE = (uint8_t)0x0C /**< 0x0C Transmit Enable and Receive Enable */ } UART4_Mode_TypeDef; /** * @brief UART4 Flag possible values */ typedef enum { UART4_FLAG_TXE = (uint16_t)0x0080, /*!< Transmit Data Register Empty flag */ UART4_FLAG_TC = (uint16_t)0x0040, /*!< Transmission Complete flag */ UART4_FLAG_RXNE = (uint16_t)0x0020, /*!< Read Data Register Not Empty flag */ UART4_FLAG_IDLE = (uint16_t)0x0010, /*!< Idle line detected flag */ UART4_FLAG_OR_LHE = (uint16_t)0x0008, /*!< OverRun error flag */ UART4_FLAG_NF = (uint16_t)0x0004, /*!< Noise error flag */ UART4_FLAG_FE = (uint16_t)0x0002, /*!< Framing Error flag */ UART4_FLAG_PE = (uint16_t)0x0001, /*!< Parity Error flag */ UART4_FLAG_SBK = (uint16_t)0x0101, /**< Send Break Complete interrupt flag */ UART4_FLAG_LBDF = (uint16_t)0x0210, /**< LIN Break Detection Flag */ UART4_FLAG_LHDF = (uint16_t)0x0302, /**< LIN Header Detection Flag*/ UART4_FLAG_LSF = (uint16_t)0x0301 /**< LIN Sync Field Flag*/ } UART4_Flag_TypeDef; /** * @brief UART4 Interrupt definition * UART4_IT possible values * Elements values convention: 0xZYX * X: Position of the corresponding Interrupt * - For the following values, X means the interrupt position in the CR2 register. * UART4_IT_TXE * UART4_IT_TC * UART4_IT_RXNE * UART4_IT_IDLE * UART4_IT_OR * - For the UART4_IT_PE value, X means the flag position in the CR1 register. * - For the UART4_IT_LBDF value, X means the flag position in the CR4 register. * - For the UART4_IT_LHDF value, X means the flag position in the CR6 register. * Y: Flag position * - For the following values, Y means the flag (pending bit) position in the SR register. * UART4_IT_TXE * UART4_IT_TC * UART4_IT_RXNE * UART4_IT_IDLE * UART4_IT_OR * UART4_IT_PE * - For the UART4_IT_LBDF value, Y means the flag position in the CR4 register. * - For the UART4_IT_LHDF value, Y means the flag position in the CR6 register. * Z: Register index: indicate in which register the dedicated interrupt source is: * - 1==> CR1 register * - 2==> CR2 register * - 3==> CR4 register * - 4==> CR6 register */ typedef enum { UART4_IT_TXE = (uint16_t)0x0277, /**< Transmit interrupt */ UART4_IT_TC = (uint16_t)0x0266, /**< Transmission Complete interrupt */ UART4_IT_RXNE = (uint16_t)0x0255, /**< Data Register Not Empty interrupt */ UART4_IT_IDLE = (uint16_t)0x0244, /**< Idle line detected interrupt */ UART4_IT_OR = (uint16_t)0x0235, /**< OverRun error interrupt */ UART4_IT_PE = (uint16_t)0x0100, /**< Parity Error interrupt */ UART4_IT_LBDF = (uint16_t)0x0346, /**< LIN Break Detection interrupt */ UART4_IT_LHDF = (uint16_t)0x0412, /**< LIN Header Detection interrupt*/ UART4_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */ } UART4_IT_TypeDef; /** * @} */ /* Exported constants --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup UART4_Private_Macros * @{ */ /** * @brief Macro used by the assert function to check the different functions parameters. */ /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the MODEs possible combination should be one of * the following. */ #define IS_UART4_MODE_OK(Mode) \ (((Mode) == (uint8_t)UART4_MODE_RX_ENABLE) || \ ((Mode) == (uint8_t)UART4_MODE_RX_DISABLE) || \ ((Mode) == (uint8_t)UART4_MODE_TX_ENABLE) || \ ((Mode) == (uint8_t)UART4_MODE_TX_DISABLE) || \ ((Mode) == (uint8_t)UART4_MODE_TXRX_ENABLE) || \ ((Mode) == (uint8_t)((uint8_t)UART4_MODE_TX_ENABLE|(uint8_t)UART4_MODE_RX_ENABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART4_MODE_TX_ENABLE|(uint8_t)UART4_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART4_MODE_TX_DISABLE|(uint8_t)UART4_MODE_RX_DISABLE)) || \ ((Mode) == (uint8_t)((uint8_t)UART4_MODE_TX_DISABLE|(uint8_t)UART4_MODE_RX_ENABLE))) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WordLengths */ #define IS_UART4_WORDLENGTH_OK(WordLength) \ (((WordLength) == UART4_WORDLENGTH_8D) || \ ((WordLength) == UART4_WORDLENGTH_9D)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the SyncModes; it should exclude values such * as UART4_CLOCK_ENABLE|UART4_CLOCK_DISABLE */ #define IS_UART4_SYNCMODE_OK(SyncMode) \ (!((((SyncMode)&(((uint8_t)UART4_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART4_SYNCMODE_CLOCK_DISABLE))) == (((uint8_t)UART4_SYNCMODE_CLOCK_ENABLE)|((uint8_t)UART4_SYNCMODE_CLOCK_DISABLE))) || \ (((SyncMode)&(((uint8_t)UART4_SYNCMODE_CPOL_LOW )|((uint8_t)UART4_SYNCMODE_CPOL_HIGH))) == (((uint8_t)UART4_SYNCMODE_CPOL_LOW )|((uint8_t)UART4_SYNCMODE_CPOL_HIGH))) || \ (((SyncMode)&(((uint8_t)UART4_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART4_SYNCMODE_CPHA_BEGINING))) == (((uint8_t)UART4_SYNCMODE_CPHA_MIDDLE)|((uint8_t)UART4_SYNCMODE_CPHA_BEGINING))) || \ (((SyncMode)&(((uint8_t)UART4_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART4_SYNCMODE_LASTBIT_ENABLE))) == (((uint8_t)UART4_SYNCMODE_LASTBIT_DISABLE)|((uint8_t)UART4_SYNCMODE_LASTBIT_ENABLE))))) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs */ #define IS_UART4_FLAG_OK(Flag) \ (((Flag) == UART4_FLAG_TXE) || \ ((Flag) == UART4_FLAG_TC) || \ ((Flag) == UART4_FLAG_RXNE) || \ ((Flag) == UART4_FLAG_IDLE) || \ ((Flag) == UART4_FLAG_OR_LHE) || \ ((Flag) == UART4_FLAG_NF) || \ ((Flag) == UART4_FLAG_FE) || \ ((Flag) == UART4_FLAG_PE) || \ ((Flag) == UART4_FLAG_SBK) || \ ((Flag) == UART4_FLAG_LSF) || \ ((Flag) == UART4_FLAG_LHDF) || \ ((Flag) == UART4_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check the * different sensitivity values for the FLAGs that can be cleared by writing 0 */ #define IS_UART4_CLEAR_FLAG_OK(Flag) \ (((Flag) == UART4_FLAG_RXNE) || \ ((Flag) == UART4_FLAG_LHDF) || \ ((Flag) == UART4_FLAG_LSF) || \ ((Flag) == UART4_FLAG_LBDF)) /** * @brief Macro used by the assert_param function in order to check * the different sensitivity values for the Interrupts */ #define IS_UART4_CONFIG_IT_OK(Interrupt) \ (((Interrupt) == UART4_IT_PE) || \ ((Interrupt) == UART4_IT_TXE) || \ ((Interrupt) == UART4_IT_TC) || \ ((Interrupt) == UART4_IT_RXNE_OR ) || \ ((Interrupt) == UART4_IT_IDLE) || \ ((Interrupt) == UART4_IT_LHDF) || \ ((Interrupt) == UART4_IT_LBDF)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit */ #define IS_UART4_GET_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART4_IT_TXE) || \ ((ITPendingBit) == UART4_IT_TC) || \ ((ITPendingBit) == UART4_IT_RXNE) || \ ((ITPendingBit) == UART4_IT_IDLE) || \ ((ITPendingBit) == UART4_IT_OR) || \ ((ITPendingBit) == UART4_IT_LBDF) || \ ((ITPendingBit) == UART4_IT_LHDF) || \ ((ITPendingBit) == UART4_IT_PE)) /** * @brief Macro used by the assert function in order to check the different * sensitivity values for the pending bit that can be cleared by writing 0 */ #define IS_UART4_CLEAR_IT_OK(ITPendingBit) \ (((ITPendingBit) == UART4_IT_RXNE) || \ ((ITPendingBit) == UART4_IT_LHDF) || \ ((ITPendingBit) == UART4_IT_LBDF)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the IrDAModes */ #define IS_UART4_IRDAMODE_OK(IrDAMode) \ (((IrDAMode) == UART4_IRDAMODE_LOWPOWER) || \ ((IrDAMode) == UART4_IRDAMODE_NORMAL)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the WakeUps */ #define IS_UART4_WAKEUP_OK(WakeUp) \ (((WakeUp) == UART4_WAKEUP_IDLELINE) || \ ((WakeUp) == UART4_WAKEUP_ADDRESSMARK)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the LINBreakDetectionLengths */ #define IS_UART4_LINBREAKDETECTIONLENGTH_OK(LINBreakDetectionLength) \ (((LINBreakDetectionLength) == UART4_LINBREAKDETECTIONLENGTH_10BITS) || \ ((LINBreakDetectionLength) == UART4_LINBREAKDETECTIONLENGTH_11BITS)) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the UART4_StopBits */ #define IS_UART4_STOPBITS_OK(StopBit) (((StopBit) == UART4_STOPBITS_1) || \ ((StopBit) == UART4_STOPBITS_0_5) || \ ((StopBit) == UART4_STOPBITS_2) || \ ((StopBit) == UART4_STOPBITS_1_5 )) /** * @brief Macro used by the assert_param function in order to check the different * sensitivity values for the Paritys */ #define IS_UART4_PARITY_OK(Parity) (((Parity) == UART4_PARITY_NO) || \ ((Parity) == UART4_PARITY_EVEN) || \ ((Parity) == UART4_PARITY_ODD )) /** * @brief Macro used by the assert_param function in order to check the maximum * baudrate value */ #define IS_UART4_BAUDRATE_OK(NUM) ((NUM) <= (uint32_t)625000) /** * @brief Macro used by the assert_param function in order to check the address * of the UART4 or UART node */ #define UART4_ADDRESS_MAX ((uint8_t)16) #define IS_UART4_ADDRESS_OK(node) ((node) < UART4_ADDRESS_MAX ) /** * @brief Macro used by the assert_param function in order to check the LIN mode */ #define IS_UART4_SLAVE_OK(Mode) \ (((Mode) == UART4_LIN_MODE_MASTER) || \ ((Mode) == UART4_LIN_MODE_SLAVE)) /** * @brief Macro used by the assert_param function in order to check the LIN * automatic resynchronization mode */ #define IS_UART4_AUTOSYNC_OK(AutosyncMode) \ (((AutosyncMode) == UART4_LIN_AUTOSYNC_ENABLE) || \ ((AutosyncMode) == UART4_LIN_AUTOSYNC_DISABLE)) /** * @brief Macro used by the assert_param function in order to check the LIN divider update method */ #define IS_UART4_DIVUP_OK(DivupMethod) \ (((DivupMethod) == UART4_LIN_DIVUP_LBRR1) || \ ((DivupMethod) == UART4_LIN_DIVUP_NEXTRXNE)) /** * @} */ /* Exported functions ------------------------------------------------------- */ /** @addtogroup UART4_Exported_Functions * @{ */ void UART4_DeInit(void); void UART4_Init(uint32_t BaudRate, UART4_WordLength_TypeDef WordLength, UART4_StopBits_TypeDef StopBits, UART4_Parity_TypeDef Parity, UART4_SyncMode_TypeDef SyncMode, UART4_Mode_TypeDef Mode); void UART4_Cmd(FunctionalState NewState); void UART4_ITConfig(UART4_IT_TypeDef UART4_IT, FunctionalState NewState); void UART4_HalfDuplexCmd(FunctionalState NewState); void UART4_IrDAConfig(UART4_IrDAMode_TypeDef UART4_IrDAMode); void UART4_IrDACmd(FunctionalState NewState); void UART4_LINBreakDetectionConfig(UART4_LINBreakDetectionLength_TypeDef UART4_LINBreakDetectionLength); void UART4_LINConfig(UART4_LinMode_TypeDef UART4_Mode, UART4_LinAutosync_TypeDef UART4_Autosync, UART4_LinDivUp_TypeDef UART4_DivUp); void UART4_LINCmd(FunctionalState NewState); void UART4_SmartCardCmd(FunctionalState NewState); void UART4_SmartCardNACKCmd(FunctionalState NewState); void UART4_WakeUpConfig(UART4_WakeUp_TypeDef UART4_WakeUp); void UART4_ReceiverWakeUpCmd(FunctionalState NewState); uint8_t UART4_ReceiveData8(void); uint16_t UART4_ReceiveData9(void); void UART4_SendData8(uint8_t Data); void UART4_SendData9(uint16_t Data); void UART4_SendBreak(void); void UART4_SetAddress(uint8_t UART4_Address); void UART4_SetGuardTime(uint8_t UART4_GuardTime); void UART4_SetPrescaler(uint8_t UART4_Prescaler); FlagStatus UART4_GetFlagStatus(UART4_Flag_TypeDef UART4_FLAG); void UART4_ClearFlag(UART4_Flag_TypeDef UART4_FLAG); ITStatus UART4_GetITStatus(UART4_IT_TypeDef UART4_IT); void UART4_ClearITPendingBit(UART4_IT_TypeDef UART4_IT); /** * @} */ #endif /* __STM8S_UART4_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/stm8s/stm8s_wwdg.h ================================================ /** ******************************************************************************** * @file stm8s_wwdg.h * @author MCD Application Team * @version V2.3.0 * @date 16-June-2017 * @brief This file contains all functions prototype and macros for the WWDG peripheral. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM8S_WWDG_H #define __STM8S_WWDG_H /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" /** @addtogroup STM8S_StdPeriph_Driver * @{ */ /* Private macros ------------------------------------------------------------*/ /** @addtogroup WWDG_Private_Macros * @{ */ /** * @brief Macro used by the assert function in order to check the * values of the window register. */ #define IS_WWDG_WINDOWLIMITVALUE_OK(WindowLimitValue) ((WindowLimitValue) <= 0x7F) /** * @brief Macro used by the assert function in order to check the different * values of the counter register. */ #define IS_WWDG_COUNTERVALUE_OK(CounterValue) ((CounterValue) <= 0x7F) /** * @} */ /* Exported types ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ /** @addtogroup WWDG_Exported_Functions * @{ */ void WWDG_Init(uint8_t Counter, uint8_t WindowValue); void WWDG_SetCounter(uint8_t Counter); uint8_t WWDG_GetCounter(void); void WWDG_SWReset(void); void WWDG_SetWindowValue(uint8_t WindowValue); /** * @} */ #endif /* __STM8S_WWDG_H */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: src/firmware/tsdz2/system.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "system.h" #include "watchdog.h" #include "cpu.h" #include "tsdz2/interrupt.h" #include "tsdz2/timers.h" #include "tsdz2/stm8s/stm8s.h" #include "tsdz2/stm8s/stm8s_clk.h" #include "tsdz2/stm8s/stm8s_tim3.h" static volatile uint32_t _ms; void system_init() { CLK->CKDIVR = 0x00; // Set 16MHz while ((CLK->ICKR & CLK_ICKR_HSIRDY) == 0); // Wait for stable clock _ms = 0; // Setup timer3 as a ms counter timer3_init_system(); enableInterrupts(); } uint32_t system_ms() { uint32_t val; uint8_t ier = TIM3->IER; TIM3->IER &= ~(TIM3_IT_UPDATE); // disable timer3 interrupt val = _ms; TIM3->IER = ier; return val; } void system_delay_ms(uint16_t ms) { if (!ms) { return; } uint32_t end = system_ms() + ms; while (system_ms() != end) { watchdog_yeild(); } } void isr_timer3_ovf(void) __interrupt(ITC_IRQ_TIM3_OVF) { _ms++; // Clear interrupt pending bit TIM3->SR1 &= (uint8_t)(~TIM3_IT_UPDATE); } ================================================ FILE: src/firmware/tsdz2/timers.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "timers.h" #include "cpu.h" #include "tsdz2/stm8s/stm8s.h" #include "tsdz2/stm8s/stm8s_clk.h" #include "tsdz2/stm8s/stm8s_tim1.h" #include "tsdz2/stm8s/stm8s_tim2.h" #include "tsdz2/stm8s/stm8s_tim3.h" #include "tsdz2/stm8s/stm8s_tim4.h" #define TIM1_AUTO_RELOAD_PERIOD 511 #define TIM2_AUTO_RELOAD_PERIOD 159 // 20us #define TIM3_AUTO_RELOAD_PERIOD 15999 // 1ms #define TIM4_AUTO_RELOAD_PERIOD 99 // 100us void timers_init() { // nothing to do here } void timer1_init_motor_pwm() { CLK->PCKENR1 |= CLK_PCKENR1_TIM1; // prescaler TIM1->PSCRH = 0; TIM1->PSCRL = 0; // auto reload // clock = 16MHz, counter period = 1024, PWM freq = 16MHz / 1024 = 15.625MHz // (BUT PWM center aligned mode needs double frequency) TIM1->ARRH = (uint8_t)(TIM1_AUTO_RELOAD_PERIOD >> 8); TIM1->ARRL = (uint8_t)TIM1_AUTO_RELOAD_PERIOD; TIM1->CR1 |= TIM1_COUNTERMODE_CENTERALIGNED1; TIM1->RCR = 1; // OC1 TIM1->CCER1 |= (uint8_t)( (uint8_t)(TIM1_OUTPUTSTATE_DISABLE & TIM1_CCER1_CC1E) | (uint8_t)(TIM1_OUTPUTNSTATE_DISABLE & TIM1_CCER1_CC1NE) | (uint8_t)(TIM1_OCPOLARITY_HIGH & TIM1_CCER1_CC1P) | (uint8_t)(TIM1_OCNPOLARITY_HIGH & TIM1_CCER1_CC1NP) ); TIM1->CCMR1 |= TIM1_OCMODE_PWM1; TIM1->OISR |= (uint8_t)( (uint8_t)(TIM1_OCIDLESTATE_RESET & TIM1_OISR_OIS1) | (uint8_t)(TIM1_OCNIDLESTATE_SET & TIM1_OISR_OIS1N) ); TIM1->CCR1H = 0; TIM1->CCR1L = 255; // OC2 TIM1->CCER1 |= (uint8_t)( (uint8_t)(TIM1_OUTPUTSTATE_DISABLE & TIM1_CCER1_CC2E) | (uint8_t)(TIM1_OUTPUTNSTATE_DISABLE & TIM1_CCER1_CC2NE) | (uint8_t)(TIM1_OCPOLARITY_HIGH & TIM1_CCER1_CC2P) | (uint8_t)(TIM1_OCNPOLARITY_HIGH & TIM1_CCER1_CC2NP) ); TIM1->CCMR2 |= TIM1_OCMODE_PWM1; TIM1->OISR |= (uint8_t)( (uint8_t)(TIM1_OCIDLESTATE_RESET & TIM1_OISR_OIS2) | (uint8_t)(TIM1_OCNIDLESTATE_SET & TIM1_OISR_OIS2N) ); TIM1->CCR2H = 0; TIM1->CCR2L = 255; // OC3 TIM1->CCER2 |= (uint8_t)( (uint8_t)(TIM1_OUTPUTSTATE_DISABLE & TIM1_CCER2_CC3E) | (uint8_t)(TIM1_OUTPUTNSTATE_DISABLE & TIM1_CCER2_CC3NE) | (uint8_t)(TIM1_OCPOLARITY_HIGH & TIM1_CCER2_CC3P) | (uint8_t)(TIM1_OCNPOLARITY_HIGH & TIM1_CCER2_CC3NP) ); TIM1->CCMR3 |= TIM1_OCMODE_PWM1; TIM1->OISR |= (uint8_t)( (uint8_t)(TIM1_OCIDLESTATE_RESET & TIM1_OISR_OIS3) | (uint8_t)(TIM1_OCNIDLESTATE_SET & TIM1_OISR_OIS3N) ); TIM1->CCR3H = 0; TIM1->CCR3L = 255; // OC4 // Used for to fire interrupt at a specific time (middle of DC link current pulses) // and is always syncronized with PWM TIM1->CCER2 |= (uint8_t)( (uint8_t)(TIM1_OUTPUTSTATE_DISABLE & TIM1_CCER2_CC4E) | (uint8_t)(TIM1_OCPOLARITY_HIGH & TIM1_CCER2_CC4P) ); TIM1->OISR &= (uint8_t)(~TIM1_OISR_OIS4); // timming for interrupt firing (hand adjusted) const uint16_t Timing = 285; TIM1->CCR4H = (uint8_t)(Timing >> 8); TIM1->CCR4L = (uint8_t)Timing; // hardware needs a dead time of 1us // 16, // DTG = 0; dead time in 62.5 ns steps; 1us/62.5ns = 16 TIM1->DTR = (uint8_t)16; TIM1->BKR = (uint8_t)( TIM1_OSSISTATE_ENABLE | TIM1_LOCKLEVEL_OFF | TIM1_BREAK_DISABLE | TIM1_BREAKPOLARITY_LOW | TIM1_AUTOMATICOUTPUT_DISABLE ); // enable cc4 interrupt TIM1->IER |= TIM1_IT_CC4; // enable timer TIM1->CR1 |= TIM1_CR1_CEN; TIM1->BKR |= TIM1_BKR_MOE; } void timer2_init_torque_sensor_pwm() { // Timer2 is used to create the pulse signal for excitation of the torque sensor circuit // Timer2 clock = 16MHz; target: 20us period --> 50khz // counter period = (1 / (16000000 / prescaler)) * (159 + 1) = 20us // set period TIM2->PSCR = TIM2_PRESCALER_2; TIM2->ARRH = (uint8_t)(TIM2_AUTO_RELOAD_PERIOD >> 8); TIM2->ARRL = (uint8_t)(TIM2_AUTO_RELOAD_PERIOD); // pulse of 2us TIM2->CCER1 |= TIM2_CCER1_CC2E; // output enable TIM2->CCMR2 |= TIM2_OCMODE_PWM1; TIM2->CCR2H = 0; TIM2->CCR2L = 16; // enable TIM2->CCMR2 |= TIM2_CCMR_OCxPE; TIM2->CR1 |= TIM2_CR1_ARPE; TIM2->CR1 |= TIM2_CR1_CEN; } void timer3_init_system() { // enable timer3 clock source CLK->PCKENR1 |= CLK_PCKENR1_TIM3; // set period TIM3->PSCR = TIM3_PRESCALER_1; TIM3->ARRH = (uint8_t)(TIM3_AUTO_RELOAD_PERIOD >> 8); TIM3->ARRL = (uint8_t)(TIM3_AUTO_RELOAD_PERIOD); // clear counter TIM3->CNTRH = 0; TIM3->CNTRL = 0; // enable TIM3 interrupt TIM3->IER |= TIM3_IT_UPDATE; // clear interrupt pending bit TIM3->SR1 &= ~TIM3_IT_UPDATE; // TIM3 enable TIM3->CR1 |= TIM3_CR1_CEN; } void timer4_init_sensors() { // enable timer4 clock source CLK->PCKENR1 |= CLK_PCKENR1_TIM4; // set period TIM4->PSCR = TIM4_PRESCALER_16; TIM4->ARR = TIM4_AUTO_RELOAD_PERIOD; // clear counter TIM4->CNTR = 0; // enable TIM4 interrupt TIM4->IER |= TIM4_IT_UPDATE; // clear interrupt pending bit TIM4->SR1 &= ~TIM4_IT_UPDATE; // TIM4 enable TIM4->CR1 |= TIM4_CR1_CEN; } ================================================ FILE: src/firmware/tsdz2/timers.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _TSDZ2_TIMERS_H_ #define _TSDZ2_TIMERS_H_ void timer1_init_motor_pwm(); void timer2_init_torque_sensor_pwm(); void timer3_init_system(); void timer4_init_sensors(); #endif ================================================ FILE: src/firmware/tsdz2/torquesensor.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include #include "system.h" #include "sensors.h" #include "adc.h" #include "util.h" #include "eventlog.h" #include "tsdz2/stm8.h" #include "tsdz2/pins.h" #include "tsdz2/stm8s/stm8s_adc1.h" #include "tsdz2/timers.h" #define AUTO_BIAS_START_TIME_MS 2000 #define AUTO_BIAS_DURATION_MS 3000 // Hard coded default torque sensor calibration table for now // // Torque sensor readings on different TSDZ2 differs by a lot. // This table is therefore not perfect for every motor but // it will have to be good enough for now. // // Default firmware has no way to calibrate, no idea if calibrations // is done at factory though. // // Consider adding manual calibration though config tool at some point. // Until then, sensitivity can be set using torque amplification factor, // which works well enough even if response will potentially not be linear. #define TORQUE_SENSOR_LUT_SIZE 8 typedef struct { uint8_t adc; uint16_t nm_x100; } torque_lut_t; static const torque_lut_t torque_sensor_lut[TORQUE_SENSOR_LUT_SIZE] = { // (adc value - bias), (Nm x 100) { 0, 0 }, // 0kg { 30, 834 }, // 5kg { 55, 1668 }, // 10kg { 78, 2502 }, // 15kg { 93, 3169 }, // 19kg { 188, 7004 }, // 42kg { 204, 8672 }, // 52kg { 224, 17511 } // 105kg }; static uint16_t torque_adc_to_nm_x100(uint16_t torque_adc) { // interpolate in lookup table if (torque_adc < torque_sensor_lut[0].adc) { // use minimum value return torque_sensor_lut[0].nm_x100; } else if (torque_adc > torque_sensor_lut[TORQUE_SENSOR_LUT_SIZE - 1].adc) { // use maximum value return torque_sensor_lut[TORQUE_SENSOR_LUT_SIZE - 1].nm_x100; } uint8_t i = 0; for (i = 0; i < TORQUE_SENSOR_LUT_SIZE - 1; i++) { if (torque_sensor_lut[i + 1].adc > torque_adc) { break; } } return (uint16_t)MAP32(torque_adc, torque_sensor_lut[i].adc, torque_sensor_lut[i + 1].adc, torque_sensor_lut[i].nm_x100, torque_sensor_lut[i + 1].nm_x100); } static uint16_t torque_nm_x100 = 0; static bool adc_bias_set = false; static uint16_t adc_bias_steps = 0; void torque_sensor_init() { SET_PIN_OUTPUT_OPEN_DRAIN(PIN_TORQUE_SENSOR_EXC); timer2_init_torque_sensor_pwm(); // some delay for torque sensor to power on system_delay_ms(50); } void torque_sensor_process() { if (adc_bias_set) { uint16_t adc_val = adc_get_torque(); if (adc_val > adc_bias_steps) { adc_val -= adc_bias_steps; } else { adc_val = 0; } // IDEA: Find max over pedal revolution period and use sin average (0.637)? // Doesn't seem to be needed, hw filtering seems to be very slow and should average just fine torque_nm_x100 = torque_adc_to_nm_x100(adc_val); } else { // find torque sensor adc bias during startup, torque sensor lookup table is relative to bias uint32_t now = system_ms(); if (now < (AUTO_BIAS_START_TIME_MS + AUTO_BIAS_DURATION_MS)) { if (now > AUTO_BIAS_START_TIME_MS) { uint16_t adc_val = adc_get_torque(); if (adc_val > adc_bias_steps) { adc_bias_steps = adc_val; } } } else { adc_bias_set = true; eventlog_write_data(EVT_DATA_TORQUE_ADC_CALIBRATED, adc_bias_steps); } } } uint16_t torque_sensor_get_nm_x100() { return torque_nm_x100; } bool torque_sensor_ok() { return !adc_bias_set || adc_bias_steps > 50; } ================================================ FILE: src/firmware/tsdz2/uart.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "uart.h" #include "interrupt.h" #include "watchdog.h" #include #define RX1_BUFFER_SIZE 64 #define RX1_BUFFER_MASK (RX1_BUFFER_SIZE - 1) #define TX1_BUFFER_SIZE 32 #define TX1_BUFFER_MASK (TX1_BUFFER_SIZE - 1) static volatile uint8_t rx1_head; static volatile uint8_t rx1_tail; static volatile uint8_t rx1_buf[RX1_BUFFER_SIZE]; static volatile uint8_t tx1_head; static volatile uint8_t tx1_tail; static volatile uint8_t tx1_sending; static volatile uint8_t tx1_buf[TX1_BUFFER_SIZE]; void uart_open(uint32_t baudrate) { rx1_head = 0; rx1_tail = 0; tx1_head = 0; tx1_tail = 0; tx1_sending = 0; // enable uart2 clock CLK->PCKENR1 |= CLK_PCKENR1_UART2; // default, 8bit, no parity, 1 stop bit etc UART2->CR1 = 0x00; UART2->CR2 = 0x00; UART2->CR3 = 0x00; // clear the LSB mantissa of UART2DIV UART2->BRR1 &= (uint8_t)(~UART2_BRR1_DIVM); // clear the MSB mantissa of UART2DIV UART2->BRR2 &= (uint8_t)(~UART2_BRR2_DIVM); // clear the fraction bits of UART2DIV UART2->BRR2 &= (uint8_t)(~UART2_BRR2_DIVF); // set the UART2 baudrate in BRR1 and BRR2 registers according to baudrate value uint32_t baud_mantissa = ((uint32_t)CPU_FREQ / (baudrate << 4)); uint32_t baud_mantissa100 = (((uint32_t)CPU_FREQ * 100) / (baudrate << 4)); uint8_t BRR2_1 = (uint8_t)((uint8_t)(((baud_mantissa100 - (baud_mantissa * 100)) << 4) / 100) & (uint8_t)0x0F); uint8_t BRR2_2 = (uint8_t)((baud_mantissa >> 4) & (uint8_t)0xF0); UART2->BRR2 = (uint8_t)(BRR2_1 | BRR2_2); UART2->BRR1 = (uint8_t)baud_mantissa; // enable rx and tx UART2->CR2 |= UART2_CR2_TEN; UART2->CR2 |= UART2_CR2_REN; // clear rx and tx interrupt flags UART2->SR &= ~UART2_SR_RXNE; // enable rx interrupts UART2->CR2 |= UART2_CR2_RIEN; } void uart_close() { UART2->BRR2 = 0x00; UART2->BRR1 = 0x00; UART2->CR1 = 0x00; UART2->CR2 = 0x00; UART2->CR3 = 0x00; } uint8_t uart_available() { return (RX1_BUFFER_SIZE + rx1_head - rx1_tail) & RX1_BUFFER_MASK; } uint8_t uart_read() { uint8_t byte = rx1_buf[rx1_tail]; rx1_tail = (rx1_tail + 1) & RX1_BUFFER_MASK; return byte; } void uart_write(uint8_t byte) { if (!tx1_sending) { tx1_sending = 1; UART2->DR = byte; UART2->CR2 |= UART2_CR2_TIEN; // enable tx done interrupt return; } uint8_t i = (tx1_head + 1) & TX1_BUFFER_MASK; // wait for free space in buffer uint8_t prev_tail = tx1_tail; while (i == tx1_tail) { if (tx1_tail != prev_tail) { prev_tail = tx1_tail; watchdog_yeild(); } } tx1_buf[tx1_head] = byte; tx1_head = i; } void uart_flush() { while (tx1_sending); } void isr_uart2_rx(void) __interrupt(ITC_IRQ_UART2_RX) { if (UART2->SR & UART2_SR_RXNE) { uint8_t c = UART2->DR; uint8_t i = (rx1_head + 1) & RX1_BUFFER_MASK; if (i != rx1_tail) { rx1_buf[rx1_head] = c; rx1_head = i; } } } void isr_uart2_tx(void) __interrupt(ITC_IRQ_UART2_TX) { if (UART2->SR & UART2_SR_TXE) { if (tx1_head != tx1_tail) { tx1_sending = 1; UART2->DR = tx1_buf[tx1_tail]; tx1_tail = (tx1_tail + 1) & TX1_BUFFER_MASK; } else { tx1_sending = 0; // no more data clear tx empty flag UART2->CR2 &= ~UART2_CR2_TIEN; } } } ================================================ FILE: src/firmware/tsdz2/watchdog.c ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #include "watchdog.h" #include "tsdz2/cpu.h" #include "tsdz2/stm8s/stm8s_iwdg.h" static bool triggered; void watchdog_init() { // :TODO: implement if possible, check if reset triggered by watchdog triggered = false; IWDG->KR = 0xcc; // start IWDG->KR = 0x55; // unlock IWDG->PR = 6; // divide by 256 IWDG->RLR = 156; // reload to 625 milliseconds watchdog_yeild(); } void watchdog_yeild() { IWDG->KR = 0xaa; } bool watchdog_triggered() { return triggered; } ================================================ FILE: src/firmware/uart.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _UART_H_ #define _UART_H_ #include void uart_open(uint32_t baudrate); void uart_close(); uint8_t uart_available(); uint8_t uart_read(); void uart_write(uint8_t byte); void uart_flush(); #endif ================================================ FILE: src/firmware/util.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _UTIL_H_ #define _UTIL_H_ #include #define MAP16(x, in_min, in_max, out_min, out_max) ((((int16_t)x) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min)) #define MAP32(x, in_min, in_max, out_min, out_max) ((((int32_t)x) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min)) #define EXPAND_U16(high, low) ((((uint16_t)high) << 8) | (uint8_t)low) #define EXPAND_I16(high, low) ((int16_t)EXPAND_U16(high,low)) #define ABS(x) (x) < 0 ? -(x) : (x) #define MAX(x, y) (x) > (y) ? (x) : (y) #define MIN(x, y) (x) < (y) ? (x) : (y) #define CLAMP(x, min, max) (MIN(MAX(x, min), max)) // Low pass filter // value + (new_value - value) / n; #define EXPONENTIAL_FILTER(value, new_value, n) (value) + ((new_value) - (value)) / (n) #endif ================================================ FILE: src/firmware/version.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _VERSION_H_ #define _VERSION_H_ #define VERSION_MAJOR 1 #define VERSION_MINOR 5 #define VERSION_PATCH 99 #if defined(BBSHD) #define CTRL_TYPE 1 #elif defined(BBS02) #define CTRL_TYPE 2 #elif defined(TSDZ2) #define CTRL_TYPE 3 #else #define CTRL_TYPE 0 #endif #endif ================================================ FILE: src/firmware/watchdog.h ================================================ /* * bbs-fw * * Copyright (C) Daniel Nilsson, 2022. * * Released under the GPL License, Version 3 */ #ifndef _WATCHDOG_H_ #define _WATCHDOG_H_ #include "intellisense.h" #include #include void watchdog_init(); void watchdog_yeild(); bool watchdog_triggered(); #endif ================================================ FILE: src/logger/.gitignore ================================================ .pio .vscode/.browse.c_cpp.db* .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch ================================================ FILE: src/logger/.vscode/extensions.json ================================================ { // See http://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format "recommendations": [ "platformio.platformio-ide" ], "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" ] } ================================================ FILE: src/logger/include/ComProxy.h ================================================ #include #include #define EVT_MSG_MOTOR_INIT_OK 1 #define EVT_MSG_CONFIG_READ 2 #define EVT_MSG_CONFIG_RESET 3 #define EVT_MSG_CONFIG_WRITTEN 4 #define EVT_ERROR_INIT_MOTOR 64 #define EVT_ERROR_CHANGE_TARGET_SPEED 65 #define EVT_ERROR_CHANGE_TARGET_CURRENT 66 #define EVT_ERROR_READ_MOTOR_STATUS 67 #define EVT_ERROR_READ_MOTOR_CURRENT 68 #define EVT_ERROR_READ_MOTOR_VOLTAGE 69 #define EVT_ERROR_CONFIG_READ_EEPROM 70 #define EVT_ERROR_CONFIG_WRITE_EEPROM 71 #define EVT_ERROR_CONFIG_ERASE_EEPROM 72 #define EVT_ERROR_CONFIG_VERSION 73 #define EVT_ERROR_CONFIG_CHECKSUM 74 #define EVT_ERROR_THROTTLE_LOW_LIMIT 75 #define EVT_ERROR_THROTTLE_HIGH_LIMIT 76 #define EVT_DATA_TARGET_CURRENT 128 #define EVT_DATA_TARGET_SPEED 129 #define EVT_DATA_MOTOR_STATUS 130 #define EVT_DATA_ASSIST_LEVEL 131 #define EVT_DATA_OPERATION_MODE 132 #define EVT_DATA_WHEEL_SPEED_PPM 133 #define EVT_DATA_LIGHTS 134 #define EVT_DATA_TEMPERATURE 135 #define EVT_DATA_THERMAL_LIMITING 136 #define EVT_DATA_SPEED_LIMITING 137 #define EVT_DATA_MAX_CURRENT_ADC_REQUEST 138 #define EVT_DATA_MAX_CURRENT_ADC_RESPONSE 139 #define EVT_DATA_MAIN_LOOP_TIME 140 #define EVT_DATA_THROTTLE_ADC 141 #define EVT_DATA_LVC_LIMITING 142 #define EVT_DATA_SHIFT_SENSOR 143 class ComProxy { public: struct Event { uint32_t timestamp; uint8_t id; int16_t data; }; static void printFormat(Stream& stream, const Event& e); ComProxy(Stream& controller, Stream& display, Stream& log); bool connect(); bool isConnected() const; void process(); bool hasLogEvent() const; bool getLogEvent(Event& e); private: void processControllerTx(); void processDisplayTx(); void flushInterceptbuffer(); bool interceptMessage(); int tryProcessControllerMessage(); int processReadRequestResponse(); int processWriteRequestResponse(); int processEventLogMessage(); private: Stream& _log; Stream& _controller; Stream& _display; bool _connected; uint8_t _msgLen; uint8_t _msgBuf[128]; uint32_t _lastRecv; bool _hasEvent; Event _event; }; ================================================ FILE: src/logger/platformio.ini ================================================ ; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:nanoatmega328] platform = atmelavr board = nanoatmega328 framework = arduino lib_deps = featherfly/SoftwareSerial@^1.0 paulstoffregen/AltSoftSerial@^1.4 upload_port = COM8 monitor_port = COM4 monitor_speed = 57600 ================================================ FILE: src/logger/src/ComProxy.cpp ================================================ #include "ComProxy.h" #define KEEP 0 #define FAIL -1 #define REQUEST_TYPE_READ 0x01 #define REQUEST_TYPE_WRITE 0x02 // Firmware config tool communication (only expected opcodes) #define OPCODE_READ_FW_VERSION 0x01 #define OPCODE_READ_EVTLOG_ENABLE 0x02 #define OPCODE_WRITE_EVTLOG_ENABLE 0xf0 #define EVENT_LOG_ENTRY 0xee #define EVENT_LOG_DATA_ENTRY 0xed static uint8_t computeChecksum(uint8_t* buf, uint8_t length) { uint8_t result = 0; for (uint8_t i = 0; i < length; ++i) { result += buf[i]; } return result; } int verifyControllerMessage(uint8_t* buf, uint8_t length, uint8_t requiredLength, Stream& log) { if (length < requiredLength) { return KEEP; } uint8_t checksum = computeChecksum(buf, requiredLength - 1); if (checksum == buf[requiredLength - 1]) { return requiredLength; } /*else { log.print("Checksum mismatch, computed="); log.print(checksum, HEX); log.print(" message="); for (uint8_t i = 0; i < requiredLength; i++) { log.print(buf[i], HEX); log.print(" "); } log.println(); }*/ return FAIL; } void ComProxy::printFormat(Stream& stream, const Event& evt) { switch (evt.id) { case EVT_MSG_MOTOR_INIT_OK: stream.print(F("Motor initialization successful.")); break; case EVT_MSG_CONFIG_READ: stream.print(F("Successfully read configuration from eeprom.")); break; case EVT_MSG_CONFIG_RESET: stream.print(F("Configuration reset performed.")); break; case EVT_MSG_CONFIG_WRITTEN: stream.print(F("Configuration written to eeprom.")); break; case EVT_ERROR_INIT_MOTOR: stream.print(F("Failed to perform motor controller initialization.")); break; case EVT_ERROR_CHANGE_TARGET_CURRENT: stream.print(F("Failed to set motor target current on motor controller.")); break; case EVT_ERROR_CHANGE_TARGET_SPEED: stream.print(F("Failed to set motor target speed on motor controller.")); break; case EVT_ERROR_READ_MOTOR_STATUS: stream.print(F("Failed to read status from motor controller.")); break; case EVT_ERROR_READ_MOTOR_CURRENT: stream.print(F("Failed to read current from motor controller.")); break; case EVT_ERROR_READ_MOTOR_VOLTAGE: stream.print(F("Failed to read voltage from motor controller.")); break; case EVT_ERROR_CONFIG_READ_EEPROM: stream.print(F("Failed to read config from eeprom.")); break; case EVT_ERROR_CONFIG_WRITE_EEPROM: stream.print(F("Failed to write config to eeprom.")); break; case EVT_ERROR_CONFIG_ERASE_EEPROM: stream.print(F("Failed to erase eeprom before writing config.")); break; case EVT_ERROR_CONFIG_VERSION: stream.print(F("Configuration read from eeprom is of the wrong version.")); break; case EVT_ERROR_CONFIG_CHECKSUM: stream.print(F("Failed to verify checksum on configuration read from eeprom.")); break; case EVT_ERROR_THROTTLE_LOW_LIMIT: stream.print(F("Invalid throttle reading, below low limit, check throttle.")); break; case EVT_ERROR_THROTTLE_HIGH_LIMIT: stream.print(F("Invalid throttle reading, above high limit, check throttle.")); break; case EVT_DATA_TARGET_CURRENT: stream.print(F("Motor target current changed to ")); stream.print(evt.data); stream.print(F("%")); break; case EVT_DATA_TARGET_SPEED: stream.print(F("Motor target speed changed to ")); stream.print((evt.data * 100) / 255); stream.print(F("%.")); break; case EVT_DATA_MOTOR_STATUS: stream.print(F("Motor controller status changed to ")); stream.print(evt.data, HEX); stream.print(F(".")); break; case EVT_DATA_ASSIST_LEVEL: stream.print(F("Assist level changed to ")); stream.print(evt.data); stream.print(F(".")); break; case EVT_DATA_OPERATION_MODE: stream.print(F("Operation mode changed to ")); stream.print(evt.data); stream.print(F(".")); break; case EVT_DATA_WHEEL_SPEED_PPM: stream.print(F("Max wheel speed changed to ")); stream.print(evt.data); stream.print(F(" rpm.")); break; case EVT_DATA_LIGHTS: stream.print(F("Lights status changed to ")); stream.print(evt.data); stream.print(F(".")); break; case EVT_DATA_TEMPERATURE: stream.print(F("Motor controller temperature changed to ")); stream.print(evt.data); stream.print(F("C.")); break; case EVT_DATA_THERMAL_LIMITING: if (evt.data != 0) { stream.print(F("Thermal limit reached, power reduced to 50%.")); } else { stream.print(F("Thermal limiting removed.")); } break; case EVT_DATA_SPEED_LIMITING: if (evt.data != 0) { stream.print(F("Speed limiting activated.")); } else { stream.print(F("Speed limiting deactivated.")); } break; case EVT_DATA_MAX_CURRENT_ADC_REQUEST: stream.print(F("Requesting to configure max current on motor controller mcu, adc=")); stream.print(evt.data); stream.print("."); break; case EVT_DATA_MAX_CURRENT_ADC_RESPONSE: stream.print(F("Max current configured on motor controller mcu, response was adc=")); stream.print(evt.data); stream.print(F(".")); break; case EVT_DATA_MAIN_LOOP_TIME: stream.print(F("Main loop, interval=")); stream.print(evt.data); stream.print(F("ms.")); break; case EVT_DATA_THROTTLE_ADC: stream.print(F("Throttle adc, value=")); stream.print(evt.data); stream.print(F(".")); break; case EVT_DATA_LVC_LIMITING: if (evt.data != 0) { stream.print(F("Low voltage limiting activated, voltage=")); stream.print(evt.data / 10.f); stream.print(F(".")); } else { stream.print("Low voltage limiting deactivated."); } break; case EVT_DATA_SHIFT_SENSOR: if (evt.data.Value != 0) { stream.print("Shift sensor power ramp started."); } else { stream.print("Shift sensor power ramp ended."); } break; default: stream.print(F("Unknown entry, id=")); stream.print(evt.id); stream.print(F(" data=")); stream.print(evt.data); break; } } ComProxy::ComProxy(Stream& controller, Stream& display, Stream& log) : _log(log) , _controller(controller) , _display(display) , _connected(false) , _msgLen(0) , _lastRecv(0) , _hasEvent(false) { } bool ComProxy::isConnected() const { return _connected; } bool ComProxy::connect() { uint8_t buffer[4]; buffer[0] = REQUEST_TYPE_WRITE; buffer[1] = OPCODE_WRITE_EVTLOG_ENABLE; buffer[2] = 1; buffer[3] = computeChecksum(buffer, 3); _controller.write(buffer, 4); uint32_t now = millis(); while(!_connected && (millis() - now) < 1000) { processControllerTx(); } return _connected; } void ComProxy::process() { processControllerTx(); processDisplayTx(); } bool ComProxy::hasLogEvent() const { return _hasEvent; } bool ComProxy::getLogEvent(Event& e) { if (_hasEvent) { e = _event; _hasEvent = false; return true; } return false; } void ComProxy::processControllerTx() { int b = -1; while ((b = _controller.read()) != -1) { _lastRecv = millis(); _msgBuf[_msgLen++] = b; int res; while (_msgLen > 0 && (res = tryProcessControllerMessage()) != KEEP) { if (res == FAIL) { _display.write(_msgBuf[0]); if (_msgLen > 1) { memcpy(_msgBuf, _msgBuf + 1, _msgLen - 1); } _msgLen--; continue; } else if (res >= 0) { // succesfully intercepted _msgLen = 0; break; } } } if (_msgLen > 0 && millis() - _lastRecv > 20) { flushInterceptbuffer(); } } void ComProxy::processDisplayTx() { int b = -1; while ((b = _display.read()) != -1) { _controller.write((uint8_t)b); } } void ComProxy::flushInterceptbuffer() { for (uint8_t i = 0; i < _msgLen; i++) { _display.write(_msgBuf[i]); } _msgLen = 0; } int ComProxy::tryProcessControllerMessage() { if (_msgLen < 1) { return KEEP; } switch (_msgBuf[0]) { case REQUEST_TYPE_READ: return processReadRequestResponse(); case REQUEST_TYPE_WRITE: return processWriteRequestResponse(); case EVENT_LOG_ENTRY: case EVENT_LOG_DATA_ENTRY: return processEventLogMessage(); } return FAIL; // unknown message, forward to display } int ComProxy::processReadRequestResponse() { if (_msgLen < 2) { return KEEP; } switch (_msgBuf[1]) { case OPCODE_READ_FW_VERSION: return verifyControllerMessage(_msgBuf, _msgLen, 7, _log); case OPCODE_READ_EVTLOG_ENABLE: return verifyControllerMessage(_msgBuf, _msgLen, 4, _log); } return FAIL; } int ComProxy::processWriteRequestResponse() { if (_msgLen < 2) { return KEEP; } switch(_msgBuf[1]) { case OPCODE_WRITE_EVTLOG_ENABLE: { if (_msgLen < 4) { return KEEP; } int res = verifyControllerMessage(_msgBuf, _msgLen, 4, _log); if (res > 0) { _connected = _msgBuf[2] != 0; } return res; }}; return FAIL; } int ComProxy::processEventLogMessage() { if (_msgBuf[0] == EVENT_LOG_ENTRY) { const int MessageSize = 3; if (_msgLen < MessageSize) { return KEEP; } int res = verifyControllerMessage(_msgBuf, _msgLen, MessageSize, _log); if (res > 0) { _hasEvent = true; _event.timestamp = millis(); _event.id = _msgBuf[1]; _event.data = 0; } return res; } else if (_msgBuf[0] == EVENT_LOG_DATA_ENTRY) { const int MessageSize = 5; if (_msgLen < MessageSize) { return KEEP; } int res = verifyControllerMessage(_msgBuf, _msgLen, MessageSize, _log); if (res > 0) { _hasEvent = true; _event.timestamp = millis(); _event.id = _msgBuf[1]; _event.data = _msgBuf[2] << 8 | _msgBuf[3]; } return res; } return FAIL; } ================================================ FILE: src/logger/src/Main.cpp ================================================ #include #include > #include "ComProxy.h" // NOTE: // This project uses a Arduno Nano based on Atmega328p. // This MCU only has a single UART. // // Two differenst software serial libraries are used // to compensate for the lack of HW ports (should have used another MCU). // // This causes a few problems since the entire CPu // is stalled when doing transmit. You may therefore see // error code 30 pop up on the display birefly if a lot is // printed to the log since the response is not fast enough. SoftwareSerial logSerial(11, 12); AltSoftSerial controllerSerial(8, 9); // HW Serial used for display connection ComProxy proxy(controllerSerial, Serial, logSerial); void initProxy() { controllerSerial.begin(1200); controllerSerial.listen(); pinMode(A2, INPUT); pinMode(A3, INPUT); // display Serial.begin(1200); if (proxy.connect()) { logSerial.println("Connected to controller."); } else { logSerial.println("Failed to connect to controller."); } } void printEvent(const ComProxy::Event& evt) { ComProxy::printFormat(logSerial, evt); logSerial.println(); } void setup() { logSerial.begin(57600); pinMode(2, INPUT_PULLUP); if (digitalRead(2)) { // Disable proxy, needed when reflashing controller to not interfere with communication pinMode(0, INPUT); pinMode(1, INPUT); pinMode(8, INPUT); pinMode(9, INPUT); logSerial.println("Logger Disabled."); } else { delay(100); initProxy(); } } void loop() { if (proxy.isConnected()) { proxy.process(); if (proxy.hasLogEvent()) { ComProxy::Event evt; if (proxy.getLogEvent(evt)) { printEvent(evt); } } } } ================================================ FILE: src/tool/.gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ [Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # ASP.NET Scaffolding ScaffoldingReadMe.txt # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Coverlet is a free, cross platform Code Coverage Tool coverage*.json coverage*.xml coverage*.info # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # NuGet Symbol Packages *.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx *.appxbundle *.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- [Bb]ackup.rdl *- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ # Fody - auto-generated XML schema FodyWeavers.xsd ================================================ FILE: src/tool/App.xaml ================================================ ================================================ FILE: src/tool/App.xaml.cs ================================================ using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Threading.Tasks; using System.Windows; namespace BBSFW { /// /// Interaction logic for App.xaml /// public partial class App : Application { } } ================================================ FILE: src/tool/AssemblyInfo.cs ================================================ using System.Windows; [assembly: ThemeInfo( ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located //(used if a resource is not found in the page, // or application resource dictionaries) ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located //(used if a resource is not found in the page, // app, or any theme specific resource dictionaries) )] ================================================ FILE: src/tool/Model/BbsfwConnection.cs ================================================ using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Management; using System.Threading; using System.Threading.Tasks; namespace BBSFW.Model { public class ComPort { public string Name { get; private set; } public string Description { get; private set; } public ComPort(string name, string description) { Name = name; Description = description; } } public class BbsfwConnection { public enum Controller { Unknown = 0, BBSHD = 1, BBS02 = 2, TSDZ2 = 3 } private const int REQUEST_TYPE_READ = 0x01; private const int REQUEST_TYPE_WRITE = 0x02; private const int RESPONSE_TYPE_READ = 0x01; private const int RESPONSE_TYPE_WRITE = 0x02; private const int EVENT_LOG_ENTRY = 0xee; private const int EVENT_LOG_DATA_ENTRY = 0xed; private const int OPCODE_READ_FW_VERSION = 0x01; private const int OPCODE_READ_EVTLOG_ENABLE = 0x02; private const int OPCODE_READ_CONFIG = 0x03; private const int OPCODE_WRITE_EVTLOG_ENABLE = 0xf0; private const int OPCODE_WRITE_CONFIG = 0xf1; private const int OPCODE_WRITE_RESET_CONFIG = 0xf2; private const int OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION = 0xf3; private const int Keep = 0; private const int Discard = -1; private SerialPort _port = null; private volatile bool _isConnecting = false; private volatile bool _isConnected = false; private Controller _controllerType = Controller.Unknown; private DateTime _lastRecv = DateTime.Now; private List _rxBuffer = new List(); private CompletionQueue _readConfigCq = new CompletionQueue(); private CompletionQueue _writeConfigCq = new CompletionQueue(); private CompletionQueue _writeResetConfigCq = new CompletionQueue(); private CompletionQueue _writeVoltageCalibrationCq = new CompletionQueue(); private int ConfigVersion = 0; public bool IsConnected { get { return _isConnected; } } public Controller ControllerType { get { return _controllerType; } } public event Action Connected; public event Action Disconnected; public event Action EventLog; public static List GetComPorts() { var result = new List(); using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%COM%'")) { var portNames = SerialPort.GetPortNames(); var ports = searcher.Get().Cast().ToList(); foreach (var name in portNames) { var port = ports.FirstOrDefault(p => p["Name"].ToString().ToUpper().Contains(name.ToUpper())); if (port != null) { result.Add(new ComPort(name, port["Caption"].ToString())); } else { result.Add(new ComPort(name, name)); } } } return result; } public async Task Connect(ComPort port, TimeSpan timeout) { _controllerType = Controller.Unknown; _isConnected = false; _isConnecting = true; _port = new SerialPort(port.Name, 1200); _port.DataReceived += OnDataReceived; _port.Open(); var connected = await Task.Run(() => SetupConnection(timeout)); if (!connected) { Close(); } return connected; } public void Close() { if (_port != null) { _isConnected = false; _isConnecting = false; _port.Close(); _port.DataReceived -= OnDataReceived; _port = null; lock (_rxBuffer) { _rxBuffer.Clear(); } Disconnected?.Invoke(); } } public async Task> ReadConfiguration(TimeSpan timeout) { SendReadRequest(OPCODE_READ_CONFIG); return await _readConfigCq.WaitResponse(timeout); } public async Task> WriteConfiguration(Configuration configuration, TimeSpan timeout) { SendWriteConfigRequest(configuration); return await _writeConfigCq.WaitResponse(timeout); } public async Task> ResetConfiguration(TimeSpan timeout) { SendWriteResetConfigRequest(); return await _writeResetConfigCq.WaitResponse(timeout); } public async Task> CalibrateBatteryVoltage(float actualVolts, TimeSpan timeout) { SendWriteVoltageCalibration(actualVolts); return await _writeVoltageCalibrationCq.WaitResponse(timeout); } private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { // check for communication error and reset if (_rxBuffer.Any() && DateTime.Now - _lastRecv > TimeSpan.FromMilliseconds(1000)) { _rxBuffer.Clear(); } bool close = false; lock(_rxBuffer) { while (_port.BytesToRead > 0) { _lastRecv = DateTime.Now; var b = _port.ReadByte(); if (b == -1) { close = true; break; } else { _rxBuffer.Add((byte)b); } } } if (close) { Close(); } else { ProcessInputBuffer(); } } private void ProcessInputBuffer() { lock(_rxBuffer) { while(true) { var result = ProcessMessage(); if (result == Discard) { System.Diagnostics.Debug.WriteLine("Discarding: " + BitConverter.ToString(_rxBuffer.ToArray()).Replace("-", " ")); _rxBuffer.Clear(); } else if (result > 0) { if (_rxBuffer.Count > result) { _rxBuffer.RemoveRange(0, result); } else { _rxBuffer.Clear(); } } else { // no data, done break; } } } } private int ProcessMessage() { if (_rxBuffer.Count < 1) { return 0; } switch(_rxBuffer[0]) { case RESPONSE_TYPE_READ: return ProcessReadResponse(); case RESPONSE_TYPE_WRITE: return ProcessWriteResponse(); case EVENT_LOG_ENTRY: case EVENT_LOG_DATA_ENTRY: return ProcessEventLogEntry(); } return Discard; } private int ProcessReadResponse() { if (_rxBuffer.Count < 2) { return 0; } switch(_rxBuffer[1]) { case OPCODE_READ_FW_VERSION: return ProcessReadResponseFwVersion(); case OPCODE_READ_EVTLOG_ENABLE: return ProcessReadResponseEvtlogEnable(); case OPCODE_READ_CONFIG: return ProcessReadResponseConfig(); } return -1; } private int ProcessReadResponseFwVersion() { const int MessageSizeV1 = 7; const int MessageSizeV2 = 8; if (_rxBuffer.Count < MessageSizeV1) { return Keep; } int size = MessageSizeV1; int major = _rxBuffer[2]; int minor = _rxBuffer[3]; int patch = _rxBuffer[4]; if (major > 1 || minor > 0) { // Controller model field added in firmware version 1.1 // Keep backwards compatibility if (_rxBuffer.Count < MessageSizeV2) { return Keep; } size = MessageSizeV2; } if (ComputeChecksum(_rxBuffer, size - 1) == _rxBuffer[size - 1]) { ConfigVersion = _rxBuffer[5]; if (_isConnecting) { _isConnecting = false; _isConnected = true; _controllerType = (size == MessageSizeV1 ? Controller.BBSHD : (Controller)_rxBuffer[6]); Connected?.Invoke(ControllerType, String.Format("{0}.{1}.{2}", major, minor, patch), ConfigVersion); ; SendEventLogEnableRequest(true); } } return size; } private int ProcessReadResponseEvtlogEnable() { const int MessageSize = 4; if (_rxBuffer.Count < MessageSize) { return Keep; } // not used return 4; } private int ProcessReadResponseConfig() { int version; if (_rxBuffer.Count > 3) { version = _rxBuffer[2]; var size = _rxBuffer[3]; if (version < Configuration.MinVersion || version > Configuration.MaxVersion || size != Configuration.GetByteSize(version)) { System.Diagnostics.Debug.WriteLine("Config read from flash is of an unsupported version or is corrupt, discarding."); return Discard; } } else { return Keep; } int MessageSize = (4 + Configuration.GetByteSize(version) + 1); if (_rxBuffer.Count < MessageSize) { return Keep; } if (ComputeChecksum(_rxBuffer, MessageSize - 1) == _rxBuffer[MessageSize - 1]) { var cfg = new Configuration(ControllerType); switch(version) { case 1: cfg.ParseFromBufferV1(_rxBuffer.Skip(4).Take(Configuration.GetByteSize(version)).ToArray()); break; case 2: cfg.ParseFromBufferV2(_rxBuffer.Skip(4).Take(Configuration.GetByteSize(version)).ToArray()); break; case 3: cfg.ParseFromBufferV3(_rxBuffer.Skip(4).Take(Configuration.GetByteSize(version)).ToArray()); break; case 4: cfg.ParseFromBufferV4(_rxBuffer.Skip(4).Take(Configuration.GetByteSize(version)).ToArray()); break; case 5: cfg.ParseFromBufferV5(_rxBuffer.Skip(4).Take(Configuration.GetByteSize(version)).ToArray()); break; } _readConfigCq.Complete(cfg); } else { System.Diagnostics.Debug.WriteLine("Config read from flash has mismatching checksum, discarding."); } return MessageSize; } private int ProcessWriteResponse() { if (_rxBuffer.Count < 2) { return Keep; } switch (_rxBuffer[1]) { case OPCODE_WRITE_EVTLOG_ENABLE: return ProcessWriteResponseEvtlogEnable(); case OPCODE_WRITE_CONFIG: return ProcessWriteResponseConfig(); case OPCODE_WRITE_RESET_CONFIG: return ProcessWriteResponseResetConfig(); case OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION: return ProcessWriteResponseVoltageCalibration(); } return Discard; } private int ProcessWriteResponseEvtlogEnable() { const int MessageSize = 4; if (_rxBuffer.Count < MessageSize) { return Keep; } // don't care return MessageSize; } private int ProcessWriteResponseConfig() { const int MessageSize = 4; if (_rxBuffer.Count < MessageSize) { return Keep; } _writeConfigCq.Complete(_rxBuffer[2] != 0); return MessageSize; } private int ProcessWriteResponseResetConfig() { const int MessageSize = 4; if (_rxBuffer.Count < MessageSize) { return Keep; } _writeResetConfigCq.Complete(_rxBuffer[2] != 0); return MessageSize; } private int ProcessWriteResponseVoltageCalibration() { const int MessageSize = 5; if (_rxBuffer.Count < MessageSize) { return Keep; } _writeVoltageCalibrationCq.Complete(true); return MessageSize; } private int ProcessEventLogEntry() { if (_rxBuffer[0] == EVENT_LOG_ENTRY) { const int MessageSize = 3; if (_rxBuffer.Count < MessageSize) { return Keep; } if (ComputeChecksum(_rxBuffer, MessageSize - 1) == _rxBuffer[MessageSize - 1]) { EventLog?.Invoke(new EventLogEntry(_rxBuffer[1], null)); return MessageSize; } else { Console.WriteLine("Event log cheksum missmatch. Discarding."); return Discard; } } else if (_rxBuffer[0] == EVENT_LOG_DATA_ENTRY) { const int MessageSize = 5; if (_rxBuffer.Count < MessageSize) { return Keep; } if (ComputeChecksum(_rxBuffer, MessageSize - 1) == _rxBuffer[MessageSize - 1]) { int data = _rxBuffer[2] << 8 | _rxBuffer[3]; EventLog?.Invoke(new EventLogEntry(_rxBuffer[1], data)); return MessageSize; } else { Console.WriteLine("Event log cheksum missmatch. Discarding."); return Discard; } } return Discard; } private void SendReadRequest(byte opcode) { var buf = new List(); buf.Add(REQUEST_TYPE_READ); buf.Add(opcode); buf.Add(ComputeChecksum(buf, buf.Count)); _port.Write(buf.ToArray(), 0, buf.Count); } private void SendEventLogEnableRequest(bool enable) { var buf = new List(); buf.Add(REQUEST_TYPE_WRITE); buf.Add(OPCODE_WRITE_EVTLOG_ENABLE); buf.Add((byte)(enable ? 1 : 0)); buf.Add(ComputeChecksum(buf, buf.Count)); _port.Write(buf.ToArray(), 0, buf.Count); } private void SendWriteConfigRequest(Configuration config) { if (Configuration.CurrentVersion != ConfigVersion) { throw new InvalidOperationException("Unsupported config version."); } var cfgarr = config.WriteToBuffer(); var buf = new List(); buf.Add(REQUEST_TYPE_WRITE); buf.Add(OPCODE_WRITE_CONFIG); buf.Add((byte)Configuration.CurrentVersion); buf.Add((byte)cfgarr.Length); buf.AddRange(cfgarr); buf.Add(ComputeChecksum(buf, buf.Count)); _port.Write(buf.ToArray(), 0, buf.Count); } private void SendWriteResetConfigRequest() { var buf = new List(); buf.Add(REQUEST_TYPE_WRITE); buf.Add(OPCODE_WRITE_RESET_CONFIG); buf.Add(ComputeChecksum(buf, buf.Count)); _port.Write(buf.ToArray(), 0, buf.Count); } private void SendWriteVoltageCalibration(float volts) { uint volts_x100 = (uint)(volts * 100); var buf = new List(); buf.Add(REQUEST_TYPE_WRITE); buf.Add(OPCODE_WRITE_ADC_VOLTAGE_CALIBRATION); buf.Add((byte)(volts_x100 >> 8)); buf.Add((byte)volts_x100); buf.Add(ComputeChecksum(buf, buf.Count)); _port.Write(buf.ToArray(), 0, buf.Count); } private bool SetupConnection(TimeSpan timeout) { var start = DateTime.Now; while (_isConnecting && !_isConnected) { if (DateTime.Now - start > timeout) { return false; } SendReadRequest(OPCODE_READ_FW_VERSION); Thread.Sleep(200); } return true; } private static byte ComputeChecksum(List buffer, int length) { unchecked { byte result = 0; for (int i = 0; i < length; i++) { result += buffer[i]; } return result; } } } } ================================================ FILE: src/tool/Model/CompletionQueue.cs ================================================ using System; using System.Threading; using System.Threading.Tasks; namespace BBSFW.Model { public class RequestResult { public bool Timeout { get; private set; } public T Result { get; private set; } public RequestResult(bool timeout, T result) { Timeout = timeout; Result = result; } } public class CompletionQueue { private TaskCompletionSource _tcs = null; public void Complete(T response) { _tcs?.SetResult(response); } public async Task> WaitResponse(TimeSpan timeout) { Reset(timeout); try { var res = await _tcs.Task; _tcs = null; return new RequestResult(false, res); } catch(TaskCanceledException) { _tcs = null; return new RequestResult(true, default(T)); } } private void Reset(TimeSpan timeout) { var tcs = new TaskCompletionSource(); var cancelTokenSrc = new CancellationTokenSource((int)timeout.TotalMilliseconds); cancelTokenSrc.Token.Register(() => tcs.TrySetCanceled()); _tcs = tcs; } } } ================================================ FILE: src/tool/Model/Configuration.cs ================================================ using System; using System.IO; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; namespace BBSFW.Model { [XmlRoot("BBSFW", Namespace ="https://github.com/danielnilsson9/bbs-fw")] public class Configuration { public const int CurrentVersion = 5; public const int MinVersion = 1; public const int MaxVersion = CurrentVersion; public const int ByteSizeV1 = 120; public const int ByteSizeV2 = 124; public const int ByteSizeV3 = 149; public const int ByteSizeV4 = 152; public const int ByteSizeV5 = 154; public enum Feature { ShiftSensor, TorqueSensor, ControllerTemperatureSensor, MotorTemperatureSensor } public static int GetByteSize(int version) { switch (version) { case 1: return ByteSizeV1; case 2: return ByteSizeV2; case 3: return ByteSizeV3; case 4: return ByteSizeV4; case 5: return ByteSizeV5; } return 0; } public enum AssistModeSelect { Off = 0, Standard = 1, Lights = 2, Pas0AndLights = 3, Pas1AndLights = 4, Pas2AndLights = 5, Pas3AndLights = 6, Pas4AndLights = 7, Pas5AndLights = 8, Pas6AndLights = 9, Pas7AndLights = 10, Pas8AndLights = 11, Pas9AndLights = 12, BrakesOnBoot = 13 } [Flags] public enum AssistFlagsType : byte { None = 0x00, Pas = 0x01, Throttle = 0x02, Cruise = 0x04, PasVariable = 0x08, PasTorque = 0x10, CadenceOverride = 0x20, SpeedOverride = 0x40 }; public enum ThrottleGlobalSpeedLimitOptions { Disabled = 0x00, Enabled = 0x01, StandardLevels = 0x02 } public enum TemperatureSensor { Disabled = 0x00, Controller = 0x01, Motor = 0x02, All = 0x03 } public enum WalkModeData { Speed = 0, Temperature = 1, RequestedPower = 2, BatteryPercent = 3 } public enum LightsModeOptions { Default = 0, Disabled = 1, AlwaysOn = 2, BrakeLight = 3 } public class AssistLevel { [XmlAttribute] public AssistFlagsType Type; [XmlAttribute] public uint MaxCurrentPercent; [XmlAttribute] public uint MaxThrottlePercent; [XmlAttribute] public uint MaxCadencePercent; [XmlAttribute] public uint MaxSpeedPercent; [XmlAttribute] public float TorqueAmplificationFactor; } [XmlIgnore] public BbsfwConnection.Controller Target { get; private set; } public uint MaxCurrentLimitAmps { get { switch (Target) { case BbsfwConnection.Controller.BBSHD: return 33; case BbsfwConnection.Controller.BBS02: return 30; case BbsfwConnection.Controller.TSDZ2: return 20; } return 50; } } // hmi [XmlIgnore] public bool UseFreedomUnits; // global public uint MaxCurrentAmps; public uint CurrentRampAmpsSecond; public float MaxBatteryVolts; public uint LowCutoffVolts; public uint MaxSpeedKph; // externals public bool UseSpeedSensor; public bool UseShiftSensor; public bool UsePushWalk; public bool UsePretension; public uint PretensionSpeedCutoffKph; public TemperatureSensor UseTemperatureSensor; // lights public LightsModeOptions LightsMode; // speed sensor public float WheelSizeInch; public uint NumWheelSensorSignals; // pas options public uint PasStartDelayPulses; public uint PasStopDelayMilliseconds; public uint PasKeepCurrentPercent; public uint PasKeepCurrentCadenceRpm; // throttle options public uint ThrottleStartMillivolts; public uint ThrottleEndMillivolts; public uint ThrottleStartPercent; public ThrottleGlobalSpeedLimitOptions ThrottleGlobalSpeedLimit; public uint ThrottleGlobalSpeedLimitPercent; // shift interrupt options public uint ShiftInterruptDuration; public uint ShiftInterruptCurrentThresholdPercent; // misc public WalkModeData WalkModeDataDisplay; // assists options public AssistModeSelect AssistModeSelection; public uint AssistStartupLevel; public AssistLevel[] StandardAssistLevels = new AssistLevel[10]; public AssistLevel[] SportAssistLevels = new AssistLevel[10]; public Configuration() : this(BbsfwConnection.Controller.Unknown) { } public Configuration(BbsfwConnection.Controller target) { Target = target; UseFreedomUnits = Properties.Settings.Default.UseFreedomUnits; MaxCurrentAmps = 0; CurrentRampAmpsSecond = 0; MaxBatteryVolts = 0; LowCutoffVolts = 0; UseSpeedSensor = false; UseShiftSensor = false; UsePushWalk = false; UsePretension = false; PretensionSpeedCutoffKph = 0; UseTemperatureSensor = TemperatureSensor.All; LightsMode = LightsModeOptions.Default; WheelSizeInch = 0; NumWheelSensorSignals = 0; MaxSpeedKph = 0; PasStartDelayPulses = 0; PasStopDelayMilliseconds = 0; PasKeepCurrentPercent = 0; PasKeepCurrentCadenceRpm = 0; ThrottleStartMillivolts = 0; ThrottleEndMillivolts = 0; ThrottleStartPercent = 0; ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled; ThrottleGlobalSpeedLimitPercent = 0; ShiftInterruptDuration = 0; ShiftInterruptCurrentThresholdPercent = 0; WalkModeDataDisplay = WalkModeData.Speed; AssistModeSelection = AssistModeSelect.Off; AssistStartupLevel = 0; for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i] = new AssistLevel(); } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i] = new AssistLevel(); } } public bool IsFeatureSupported(Feature feature) { if (Target == BbsfwConnection.Controller.Unknown) { return true; } switch (feature) { case Feature.ShiftSensor: return new[] { BbsfwConnection.Controller.BBSHD, BbsfwConnection.Controller.BBS02 }.Contains(Target); case Feature.TorqueSensor: return new[] { BbsfwConnection.Controller.TSDZ2 }.Contains(Target); case Feature.ControllerTemperatureSensor: return new[] { BbsfwConnection.Controller.BBSHD, BbsfwConnection.Controller.BBS02 }.Contains(Target); case Feature.MotorTemperatureSensor: return new[] { BbsfwConnection.Controller.BBSHD }.Contains(Target); } return false; } public bool ParseFromBufferV1(byte[] buffer) { if (buffer.Length != ByteSizeV1) { return false; } using (var s = new MemoryStream(buffer)) { var br = new BinaryReader(s); UseFreedomUnits = br.ReadBoolean(); MaxCurrentAmps = br.ReadByte(); CurrentRampAmpsSecond = br.ReadByte(); LowCutoffVolts = br.ReadByte(); MaxSpeedKph = br.ReadByte(); UseSpeedSensor = br.ReadBoolean(); /* UseDisplay = */ br.ReadBoolean(); UsePushWalk = br.ReadBoolean(); WheelSizeInch = br.ReadUInt16() / 10f; NumWheelSensorSignals = br.ReadByte(); PasStartDelayPulses = br.ReadByte(); PasStopDelayMilliseconds = br.ReadByte() * 10u; ThrottleStartMillivolts = br.ReadUInt16(); ThrottleEndMillivolts = br.ReadUInt16(); ThrottleStartPercent = br.ReadByte(); AssistModeSelection = (AssistModeSelect)br.ReadByte(); AssistStartupLevel = br.ReadByte(); for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); StandardAssistLevels[i].MaxCurrentPercent = br.ReadByte(); StandardAssistLevels[i].MaxThrottlePercent = br.ReadByte(); StandardAssistLevels[i].MaxCadencePercent = br.ReadByte(); StandardAssistLevels[i].MaxSpeedPercent = br.ReadByte(); } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); SportAssistLevels[i].MaxCurrentPercent = br.ReadByte(); SportAssistLevels[i].MaxThrottlePercent = br.ReadByte(); SportAssistLevels[i].MaxCadencePercent = br.ReadByte(); SportAssistLevels[i].MaxSpeedPercent = br.ReadByte(); } } // apply default settings for non existing options in version MaxBatteryVolts = 0f; UseTemperatureSensor = TemperatureSensor.All; WalkModeDataDisplay = WalkModeData.Speed; PasKeepCurrentPercent = 100; PasKeepCurrentCadenceRpm = 255; UseShiftSensor = true; ShiftInterruptDuration = 600; ShiftInterruptCurrentThresholdPercent = 10; LightsMode = LightsModeOptions.Default; UsePretension = false; PretensionSpeedCutoffKph = 16; ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled; ThrottleGlobalSpeedLimitPercent = 100; UsePretension = false; PretensionSpeedCutoffKph = 0; return true; } public bool ParseFromBufferV2(byte[] buffer) { if (buffer.Length != ByteSizeV2) { return false; } using (var s = new MemoryStream(buffer)) { var br = new BinaryReader(s); UseFreedomUnits = br.ReadBoolean(); MaxCurrentAmps = br.ReadByte(); CurrentRampAmpsSecond = br.ReadByte(); MaxBatteryVolts = br.ReadUInt16() / 100f; LowCutoffVolts = br.ReadByte(); MaxSpeedKph = br.ReadByte(); UseSpeedSensor = br.ReadBoolean(); /* UseDisplay = */ br.ReadBoolean(); UsePushWalk = br.ReadBoolean(); UseTemperatureSensor = (TemperatureSensor)br.ReadByte(); WheelSizeInch = br.ReadUInt16() / 10f; NumWheelSensorSignals = br.ReadByte(); PasStartDelayPulses = br.ReadByte(); PasStopDelayMilliseconds = br.ReadByte() * 10u; PasKeepCurrentCadenceRpm = 255; PasKeepCurrentPercent = 100; ThrottleStartMillivolts = br.ReadUInt16(); ThrottleEndMillivolts = br.ReadUInt16(); ThrottleStartPercent = br.ReadByte(); WalkModeDataDisplay = (WalkModeData)br.ReadByte(); AssistModeSelection = (AssistModeSelect)br.ReadByte(); AssistStartupLevel = br.ReadByte(); for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); StandardAssistLevels[i].MaxCurrentPercent = br.ReadByte(); StandardAssistLevels[i].MaxThrottlePercent = br.ReadByte(); StandardAssistLevels[i].MaxCadencePercent = br.ReadByte(); StandardAssistLevels[i].MaxSpeedPercent = br.ReadByte(); } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); SportAssistLevels[i].MaxCurrentPercent = br.ReadByte(); SportAssistLevels[i].MaxThrottlePercent = br.ReadByte(); SportAssistLevels[i].MaxCadencePercent = br.ReadByte(); SportAssistLevels[i].MaxSpeedPercent = br.ReadByte(); } } // apply default settings for non existing options in version PasKeepCurrentPercent = 100; PasKeepCurrentCadenceRpm = 255; UseShiftSensor = true; ShiftInterruptDuration = 600; ShiftInterruptCurrentThresholdPercent = 10; LightsMode = LightsModeOptions.Default; UsePretension = false; PretensionSpeedCutoffKph = 16; ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled; ThrottleGlobalSpeedLimitPercent = 100; UsePretension = false; PretensionSpeedCutoffKph = 0; return true; } public bool ParseFromBufferV3(byte[] buffer) { if (buffer.Length != ByteSizeV3) { return false; } using (var s = new MemoryStream(buffer)) { var br = new BinaryReader(s); UseFreedomUnits = br.ReadBoolean(); MaxCurrentAmps = br.ReadByte(); CurrentRampAmpsSecond = br.ReadByte(); MaxBatteryVolts = br.ReadUInt16() / 100f; LowCutoffVolts = br.ReadByte(); MaxSpeedKph = br.ReadByte(); UseSpeedSensor = br.ReadBoolean(); UseShiftSensor = br.ReadBoolean(); UsePushWalk = br.ReadBoolean(); UseTemperatureSensor = (TemperatureSensor)br.ReadByte(); WheelSizeInch = br.ReadUInt16() / 10f; NumWheelSensorSignals = br.ReadByte(); PasStartDelayPulses = br.ReadByte(); PasStopDelayMilliseconds = br.ReadByte() * 10u; PasKeepCurrentPercent = br.ReadByte(); PasKeepCurrentCadenceRpm = br.ReadByte(); ThrottleStartMillivolts = br.ReadUInt16(); ThrottleEndMillivolts = br.ReadUInt16(); ThrottleStartPercent = br.ReadByte(); ShiftInterruptDuration = br.ReadUInt16(); ShiftInterruptCurrentThresholdPercent = br.ReadByte(); WalkModeDataDisplay = (WalkModeData)br.ReadByte(); AssistModeSelection = (AssistModeSelect)br.ReadByte(); AssistStartupLevel = br.ReadByte(); for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); StandardAssistLevels[i].MaxCurrentPercent = br.ReadByte(); StandardAssistLevels[i].MaxThrottlePercent = br.ReadByte(); StandardAssistLevels[i].MaxCadencePercent = br.ReadByte(); StandardAssistLevels[i].MaxSpeedPercent = br.ReadByte(); StandardAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); SportAssistLevels[i].MaxCurrentPercent = br.ReadByte(); SportAssistLevels[i].MaxThrottlePercent = br.ReadByte(); SportAssistLevels[i].MaxCadencePercent = br.ReadByte(); SportAssistLevels[i].MaxSpeedPercent = br.ReadByte(); SportAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } } // apply default settings for non existing options in version LightsMode = LightsModeOptions.Default; ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled; ThrottleGlobalSpeedLimitPercent = 100; UsePretension = false; PretensionSpeedCutoffKph = 0; return true; } public bool ParseFromBufferV4(byte[] buffer) { if (buffer.Length != ByteSizeV4) { return false; } using (var s = new MemoryStream(buffer)) { var br = new BinaryReader(s); UseFreedomUnits = br.ReadBoolean(); MaxCurrentAmps = br.ReadByte(); CurrentRampAmpsSecond = br.ReadByte(); MaxBatteryVolts = br.ReadUInt16() / 100f; LowCutoffVolts = br.ReadByte(); MaxSpeedKph = br.ReadByte(); UseSpeedSensor = br.ReadBoolean(); UseShiftSensor = br.ReadBoolean(); UsePushWalk = br.ReadBoolean(); UseTemperatureSensor = (TemperatureSensor)br.ReadByte(); LightsMode = (LightsModeOptions)br.ReadByte(); WheelSizeInch = br.ReadUInt16() / 10f; NumWheelSensorSignals = br.ReadByte(); PasStartDelayPulses = br.ReadByte(); PasStopDelayMilliseconds = br.ReadByte() * 10u; PasKeepCurrentPercent = br.ReadByte(); PasKeepCurrentCadenceRpm = br.ReadByte(); ThrottleStartMillivolts = br.ReadUInt16(); ThrottleEndMillivolts = br.ReadUInt16(); ThrottleStartPercent = br.ReadByte(); ThrottleGlobalSpeedLimit = (ThrottleGlobalSpeedLimitOptions)br.ReadByte(); ThrottleGlobalSpeedLimitPercent = br.ReadByte(); ShiftInterruptDuration = br.ReadUInt16(); ShiftInterruptCurrentThresholdPercent = br.ReadByte(); WalkModeDataDisplay = (WalkModeData)br.ReadByte(); AssistModeSelection = (AssistModeSelect)br.ReadByte(); AssistStartupLevel = br.ReadByte(); for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); StandardAssistLevels[i].MaxCurrentPercent = br.ReadByte(); StandardAssistLevels[i].MaxThrottlePercent = br.ReadByte(); StandardAssistLevels[i].MaxCadencePercent = br.ReadByte(); StandardAssistLevels[i].MaxSpeedPercent = br.ReadByte(); StandardAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); SportAssistLevels[i].MaxCurrentPercent = br.ReadByte(); SportAssistLevels[i].MaxThrottlePercent = br.ReadByte(); SportAssistLevels[i].MaxCadencePercent = br.ReadByte(); SportAssistLevels[i].MaxSpeedPercent = br.ReadByte(); SportAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } } // apply default settings for non existing options in version UsePretension = false; PretensionSpeedCutoffKph = 0; return true; } public bool ParseFromBufferV5(byte[] buffer) { if (buffer.Length != ByteSizeV5) { return false; } using (var s = new MemoryStream(buffer)) { var br = new BinaryReader(s); UseFreedomUnits = br.ReadBoolean(); MaxCurrentAmps = br.ReadByte(); CurrentRampAmpsSecond = br.ReadByte(); MaxBatteryVolts = br.ReadUInt16() / 100f; LowCutoffVolts = br.ReadByte(); MaxSpeedKph = br.ReadByte(); UseSpeedSensor = br.ReadBoolean(); UseShiftSensor = br.ReadBoolean(); UsePushWalk = br.ReadBoolean(); UseTemperatureSensor = (TemperatureSensor)br.ReadByte(); LightsMode = (LightsModeOptions)br.ReadByte(); UsePretension = br.ReadBoolean(); PretensionSpeedCutoffKph = br.ReadByte(); WheelSizeInch = br.ReadUInt16() / 10f; NumWheelSensorSignals = br.ReadByte(); PasStartDelayPulses = br.ReadByte(); PasStopDelayMilliseconds = br.ReadByte() * 10u; PasKeepCurrentPercent = br.ReadByte(); PasKeepCurrentCadenceRpm = br.ReadByte(); ThrottleStartMillivolts = br.ReadUInt16(); ThrottleEndMillivolts = br.ReadUInt16(); ThrottleStartPercent = br.ReadByte(); ThrottleGlobalSpeedLimit = (ThrottleGlobalSpeedLimitOptions)br.ReadByte(); ThrottleGlobalSpeedLimitPercent = br.ReadByte(); ShiftInterruptDuration = br.ReadUInt16(); ShiftInterruptCurrentThresholdPercent = br.ReadByte(); WalkModeDataDisplay = (WalkModeData)br.ReadByte(); AssistModeSelection = (AssistModeSelect)br.ReadByte(); AssistStartupLevel = br.ReadByte(); for (int i = 0; i < StandardAssistLevels.Length; ++i) { StandardAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); StandardAssistLevels[i].MaxCurrentPercent = br.ReadByte(); StandardAssistLevels[i].MaxThrottlePercent = br.ReadByte(); StandardAssistLevels[i].MaxCadencePercent = br.ReadByte(); StandardAssistLevels[i].MaxSpeedPercent = br.ReadByte(); StandardAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } for (int i = 0; i < SportAssistLevels.Length; ++i) { SportAssistLevels[i].Type = (AssistFlagsType)br.ReadByte(); SportAssistLevels[i].MaxCurrentPercent = br.ReadByte(); SportAssistLevels[i].MaxThrottlePercent = br.ReadByte(); SportAssistLevels[i].MaxCadencePercent = br.ReadByte(); SportAssistLevels[i].MaxSpeedPercent = br.ReadByte(); SportAssistLevels[i].TorqueAmplificationFactor = br.ReadByte() / 10f; } } return true; } public byte[] WriteToBuffer() { using (var s = new MemoryStream()) { var bw = new BinaryWriter(s); bw.Write(UseFreedomUnits); bw.Write((byte)MaxCurrentAmps); bw.Write((byte)CurrentRampAmpsSecond); bw.Write((UInt16)(MaxBatteryVolts * 100)); bw.Write((byte)LowCutoffVolts); bw.Write((byte)MaxSpeedKph); bw.Write(UseSpeedSensor); bw.Write(UseShiftSensor); bw.Write(UsePushWalk); bw.Write((byte)UseTemperatureSensor); bw.Write((byte)LightsMode); bw.Write(UsePretension); bw.Write((byte)PretensionSpeedCutoffKph); bw.Write((UInt16)(WheelSizeInch * 10)); bw.Write((byte)NumWheelSensorSignals); bw.Write((byte)PasStartDelayPulses); bw.Write((byte)(PasStopDelayMilliseconds / 10u)); bw.Write((byte)PasKeepCurrentPercent); bw.Write((byte)PasKeepCurrentCadenceRpm); bw.Write((UInt16)ThrottleStartMillivolts); bw.Write((UInt16)ThrottleEndMillivolts); bw.Write((byte)ThrottleStartPercent); bw.Write((byte)ThrottleGlobalSpeedLimit); bw.Write((byte)ThrottleGlobalSpeedLimitPercent); bw.Write((UInt16)ShiftInterruptDuration); bw.Write((byte)ShiftInterruptCurrentThresholdPercent); bw.Write((byte)WalkModeDataDisplay); bw.Write((byte)AssistModeSelection); bw.Write((byte)AssistStartupLevel); for (int i = 0; i < StandardAssistLevels.Length; ++i) { bw.Write((byte)StandardAssistLevels[i].Type); bw.Write((byte)StandardAssistLevels[i].MaxCurrentPercent); bw.Write((byte)StandardAssistLevels[i].MaxThrottlePercent); bw.Write((byte)StandardAssistLevels[i].MaxCadencePercent); bw.Write((byte)StandardAssistLevels[i].MaxSpeedPercent); bw.Write((byte)Math.Round(StandardAssistLevels[i].TorqueAmplificationFactor * 10)); } for (int i = 0; i < SportAssistLevels.Length; ++i) { bw.Write((byte)SportAssistLevels[i].Type); bw.Write((byte)SportAssistLevels[i].MaxCurrentPercent); bw.Write((byte)SportAssistLevels[i].MaxThrottlePercent); bw.Write((byte)SportAssistLevels[i].MaxCadencePercent); bw.Write((byte)SportAssistLevels[i].MaxSpeedPercent); bw.Write((byte)Math.Round(SportAssistLevels[i].TorqueAmplificationFactor * 10)); } return s.ToArray(); } } public void CopyFrom(Configuration cfg) { Target = cfg.Target; UseFreedomUnits = cfg.UseFreedomUnits; MaxCurrentAmps = cfg.MaxCurrentAmps; CurrentRampAmpsSecond = cfg.CurrentRampAmpsSecond; MaxBatteryVolts = cfg.MaxBatteryVolts; LowCutoffVolts = cfg.LowCutoffVolts; UseSpeedSensor = cfg.UseSpeedSensor; UseShiftSensor = cfg.UseShiftSensor; UsePushWalk = cfg.UsePushWalk; UsePretension = cfg.UsePretension; PretensionSpeedCutoffKph = cfg.PretensionSpeedCutoffKph; UseTemperatureSensor = cfg.UseTemperatureSensor; LightsMode = cfg.LightsMode; WheelSizeInch = cfg.WheelSizeInch; NumWheelSensorSignals = cfg.NumWheelSensorSignals; MaxSpeedKph = cfg.MaxSpeedKph; PasStartDelayPulses = cfg.PasStartDelayPulses; PasStopDelayMilliseconds = cfg.PasStopDelayMilliseconds; PasKeepCurrentPercent = cfg.PasKeepCurrentPercent; PasKeepCurrentCadenceRpm = cfg.PasKeepCurrentCadenceRpm; ThrottleStartMillivolts = cfg.ThrottleStartMillivolts; ThrottleEndMillivolts = cfg.ThrottleEndMillivolts; ThrottleStartPercent = cfg.ThrottleStartPercent; ThrottleGlobalSpeedLimit = cfg.ThrottleGlobalSpeedLimit; ThrottleGlobalSpeedLimitPercent = cfg.ThrottleGlobalSpeedLimitPercent; ShiftInterruptDuration = cfg.ShiftInterruptDuration; ShiftInterruptCurrentThresholdPercent = cfg.ShiftInterruptCurrentThresholdPercent; WalkModeDataDisplay = cfg.WalkModeDataDisplay; AssistModeSelection = cfg.AssistModeSelection; AssistStartupLevel = cfg.AssistStartupLevel; for (int i = 0; i < Math.Min(cfg.StandardAssistLevels.Length, StandardAssistLevels.Length); ++i) { StandardAssistLevels[i].Type = cfg.StandardAssistLevels[i].Type; StandardAssistLevels[i].MaxCurrentPercent = cfg.StandardAssistLevels[i].MaxCurrentPercent; StandardAssistLevels[i].MaxThrottlePercent = cfg.StandardAssistLevels[i].MaxThrottlePercent; StandardAssistLevels[i].MaxCadencePercent = cfg.StandardAssistLevels[i].MaxCadencePercent; StandardAssistLevels[i].MaxSpeedPercent = cfg.StandardAssistLevels[i].MaxSpeedPercent; StandardAssistLevels[i].TorqueAmplificationFactor = cfg.StandardAssistLevels[i].TorqueAmplificationFactor; } for (int i = 0; i < Math.Min(cfg.SportAssistLevels.Length, SportAssistLevels.Length); ++i) { SportAssistLevels[i].Type = cfg.SportAssistLevels[i].Type; SportAssistLevels[i].MaxCurrentPercent = cfg.SportAssistLevels[i].MaxCurrentPercent; SportAssistLevels[i].MaxThrottlePercent = cfg.SportAssistLevels[i].MaxThrottlePercent; SportAssistLevels[i].MaxCadencePercent = cfg.SportAssistLevels[i].MaxCadencePercent; SportAssistLevels[i].MaxSpeedPercent = cfg.SportAssistLevels[i].MaxSpeedPercent; SportAssistLevels[i].TorqueAmplificationFactor = cfg.SportAssistLevels[i].TorqueAmplificationFactor; } } public void ReadFromFile(string filepath) { var serializer = new XmlSerializer(typeof(Configuration)); using (var reader = new FileStream(filepath, FileMode.Open)) { var obj = serializer.Deserialize(reader) as Configuration; CopyFrom(obj); } } public void WriteToFile(string filepath) { var serializer = new XmlSerializer(typeof(Configuration)); var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; using (var xmlWriter = XmlWriter.Create(new StreamWriter(filepath), settings)) { serializer.Serialize(xmlWriter, this); } } public void Validate() { ValidateLimits(MaxCurrentAmps, 5, MaxCurrentLimitAmps, "Max Current (A)"); ValidateLimits(CurrentRampAmpsSecond, 1, 255, "Current Ramp (A/s)"); ValidateLimits((uint)MaxBatteryVolts, 1, 100, "Max Battery Voltage (V)"); ValidateLimits(LowCutoffVolts, 1, 100, "Low Voltage Cut Off (V)"); ValidateLimits((uint)WheelSizeInch, 10, 40, "Wheel Size (inch)"); ValidateLimits(NumWheelSensorSignals, 1, 10, "Wheel Sensor Signals"); ValidateLimits(MaxSpeedKph, 0, 180, "Max Speed (km/h)"); ValidateLimits(PretensionSpeedCutoffKph, 0, 100, "Pretension Speed Cutoff (km/h)"); ValidateLimits(PasStartDelayPulses, 0, 24, "Pas Delay (pulses)"); ValidateLimits(PasStopDelayMilliseconds, 50, 1000, "Pas Stop Delay (ms)"); ValidateLimits(PasKeepCurrentPercent, 10, 100, "Pas Keep Current (%)"); ValidateLimits(PasKeepCurrentCadenceRpm, 0, 255, "Pas Keep Current Cadence (rpm)"); ValidateLimits(ThrottleStartMillivolts, 200, 2500, "Throttle Start (mV)"); ValidateLimits(ThrottleEndMillivolts, 2500, 5000, "Throttle End (mV)"); ValidateLimits(ThrottleStartPercent, 0, 100, "Throttle Start (%)"); ValidateLimits(ThrottleGlobalSpeedLimitPercent, 0, 100, "Throttle Global Speed Limit (%)"); ValidateLimits(ShiftInterruptDuration, 50, 2000, "Shift Interrupt Duration (ms)"); ValidateLimits(ShiftInterruptCurrentThresholdPercent, 0, 100, "Shift Interrupt Current Threshold (%)"); ValidateLimits(AssistStartupLevel, 0, 9, "Assist Startup Level"); for (int i = 0; i < StandardAssistLevels.Length; ++i) { ValidateLimits(StandardAssistLevels[i].MaxCurrentPercent, 0, 100, $"Standard (Level {i}): Target Power (%)"); ValidateLimits(StandardAssistLevels[i].MaxThrottlePercent, 0, 100, $"Standard (Level {i}): Max Throttle (%)"); ValidateLimits(StandardAssistLevels[i].MaxCadencePercent, 0, 100, $"Standard (Level {i}): Max Cadence (%)"); ValidateLimits(StandardAssistLevels[i].MaxSpeedPercent, 0, 100, $"Standard (Level {i}): Max Speed (%)"); ValidateLimits((uint)StandardAssistLevels[i].TorqueAmplificationFactor, 0, 25, $"Standard (Level {i}): Torque Amplification"); } for (int i = 0; i < SportAssistLevels.Length; ++i) { ValidateLimits(SportAssistLevels[i].MaxCurrentPercent, 0, 100, $"Sport (Level {i}): Target Power (%)"); ValidateLimits(SportAssistLevels[i].MaxThrottlePercent, 0, 100, $"Sport (Level {i}): Max Throttle (%)"); ValidateLimits(SportAssistLevels[i].MaxCadencePercent, 0, 100, $"Sport (Level {i}): Max Cadence (%)"); ValidateLimits(SportAssistLevels[i].MaxSpeedPercent, 0, 100, $"Sport (Level {i}): Max Speed (%)"); ValidateLimits((uint)SportAssistLevels[i].TorqueAmplificationFactor, 0, 25, $"Sport (Level {i}): Torque Amplification"); } } private void ValidateLimits(uint value, uint min, uint max, string name) { if (value < min || value > max) { throw new Exception(name + " must be in interval " + min + "-" + max + "."); } } } } ================================================ FILE: src/tool/Model/EventLogEntry.cs ================================================ using System; namespace BBSFW.Model { public class EventLogEntry { private int _event; private int? _data; private const int EVT_MSG_MOTOR_INIT_OK = 1; private const int EVT_MSG_CONFIG_READ_DONE = 2; private const int EVT_MSG_CONFIG_RESET = 3; private const int EVT_MSG_CONFIG_WRITE_DONE = 4; private const int EVT_MSG_CONFIG_READ_BEGIN = 5; private const int EVT_MSG_CONFIG_WRITE_BEGIN = 6; private const int EVT_MSG_PSTATE_READ_BEGIN = 7; private const int EVT_MSG_PSTATE_READ_DONE = 8; private const int EVT_MSG_PSTATE_WRITE_BEGIN = 9; private const int EVT_MSG_PSTATE_WRITE_DONE = 10; private const int EVT_ERROR_INIT_MOTOR = 64; private const int EVT_ERROR_CHANGE_TARGET_SPEED = 65; private const int EVT_ERROR_CHANGE_TARGET_CURRENT = 66; private const int EVT_ERROR_READ_MOTOR_STATUS = 67; private const int EVT_ERROR_READ_MOTOR_CURRENT = 68; private const int EVT_ERROR_READ_MOTOR_VOLTAGE = 69; private const int EVT_ERROR_EEPROM_READ = 70; private const int EVT_ERROR_EEPROM_WRITE = 71; private const int EVT_ERROR_EEPROM_ERASE = 72; private const int EVT_ERROR_EEPROM_VERIFY_VERSION = 73; private const int EVT_ERROR_EEPROM_VERIFY_CHECKSUM = 74; private const int EVT_ERROR_THROTTLE_LOW_LIMIT = 75; private const int EVT_ERROR_THROTTLE_HIGH_LIMIT = 76; private const int EVT_ERROR_WATCHDOG_TRIGGERED = 77; private const int EVT_ERROR_EXTCOM_CHECKSUM = 78; private const int EVT_ERROR_EXTCOM_DISCARD = 79; private const int EVT_DATA_TARGET_CURRENT = 128; private const int EVT_DATA_TARGET_SPEED = 129; private const int EVT_DATA_MOTOR_STATUS = 130; private const int EVT_DATA_ASSIST_LEVEL = 131; private const int EVT_DATA_OPERATION_MODE = 132; private const int EVT_DATA_WHEEL_SPEED_PPM = 133; private const int EVT_DATA_LIGHTS = 134; private const int EVT_DATA_TEMPERATURE = 135; private const int EVT_DATA_THERMAL_LIMITING = 136; private const int EVT_DATA_SPEED_LIMITING = 137; private const int EVT_DATA_MAX_CURRENT_ADC_REQUEST = 138; private const int EVT_DATA_MAX_CURRENT_ADC_RESPONSE = 139; private const int EVT_DATA_MAIN_LOOP_TIME = 140; private const int EVT_DATA_THROTTLE_ADC = 141; private const int EVT_DATA_LVC_LIMITING = 142; private const int EVT_DATA_SHIFT_SENSOR = 143; private const int EVT_DATA_BBSHD_THERMISTOR = 144; private const int EVT_DATA_VOLTAGE = 145; private const int EVT_DATA_VOLTAGE_CALIBRATION = 146; private const int EVT_DATA_TORQUE_ADC = 147; private const int EVT_DATA_TORQUE_ADC_CALIBRATED = 148; public enum LogLevel { Info, Warning, Error } public DateTime Timestamp { get; private set; } public LogLevel Level { get; private set; } public string Message { get; private set; } public EventLogEntry(int evt, int? data) { Timestamp = DateTime.Now; _event = evt; if (evt >= 64 & evt < 128) { Level = LogLevel.Error; } else { Level = LogLevel.Info; } _data = data; Message = Parse(); } public string Parse() { switch (_event) { case EVT_MSG_MOTOR_INIT_OK: return "Motor initialization successful."; case EVT_MSG_CONFIG_READ_DONE: return "Successfully read configuration from eeprom."; case EVT_MSG_CONFIG_RESET: Level = LogLevel.Warning; return "Configuration reset performed."; case EVT_MSG_CONFIG_WRITE_DONE: return "Configuration successfully written to eeprom."; case EVT_MSG_CONFIG_READ_BEGIN: return "Reading configuration from eeprom."; case EVT_MSG_CONFIG_WRITE_BEGIN: return "Writing configuration to eeprom."; case EVT_MSG_PSTATE_READ_BEGIN: return "Reading persisted state from eeprom."; case EVT_MSG_PSTATE_READ_DONE: return "Successfully read persisted state from eeprom."; case EVT_MSG_PSTATE_WRITE_BEGIN: return "Writing persisted stated to eeprom."; case EVT_MSG_PSTATE_WRITE_DONE: return "Persisted state successfully written to eeprom."; case EVT_ERROR_INIT_MOTOR: return "Failed to perform motor controller initialization."; case EVT_ERROR_CHANGE_TARGET_CURRENT: return "Failed to set motor target current on motor controller."; case EVT_ERROR_CHANGE_TARGET_SPEED: return "Failed to set motor target speed on motor controller."; case EVT_ERROR_READ_MOTOR_STATUS: return "Failed to read status from motor controller."; case EVT_ERROR_READ_MOTOR_CURRENT: return "Failed to read current from motor controller."; case EVT_ERROR_READ_MOTOR_VOLTAGE: return "Failed to read voltage from motor controller."; case EVT_ERROR_EEPROM_READ: return "Failed to read data from eeprom."; case EVT_ERROR_EEPROM_WRITE: return "Failed to write data to eeprom."; case EVT_ERROR_EEPROM_ERASE: return "Failed to erase eeprom before writing data."; case EVT_ERROR_EEPROM_VERIFY_VERSION: return "Data read from eeprom is of the wrong version."; case EVT_ERROR_EEPROM_VERIFY_CHECKSUM: return "Failed to verify checksum on data read from eeprom."; case EVT_ERROR_THROTTLE_LOW_LIMIT: return "Invalid throttle reading, below low limit, check throttle."; case EVT_ERROR_THROTTLE_HIGH_LIMIT: return "Invalid throttle reading, above high limit, check throttle."; case EVT_ERROR_WATCHDOG_TRIGGERED: return "Software reset by watchdog, software error."; case EVT_ERROR_EXTCOM_CHECKSUM: return "Message received with invalid checksum."; case EVT_ERROR_EXTCOM_DISCARD: return "Invalid message received on serial port, discarded."; case EVT_DATA_TARGET_CURRENT: return $"Motor target current changed to {_data}%."; case EVT_DATA_TARGET_SPEED: return $"Motor target speed changed to {_data}%."; case EVT_DATA_MOTOR_STATUS: Level = _data != 0 ? LogLevel.Error : LogLevel.Info; return $"Motor controller status changed to 0x{_data:X}."; case EVT_DATA_ASSIST_LEVEL: return $"Assist level changed to {_data}."; case EVT_DATA_OPERATION_MODE: return $"Operation mode changed to {_data}."; case EVT_DATA_WHEEL_SPEED_PPM: return $"Max wheel speed changed to {_data} rpm."; case EVT_DATA_LIGHTS: return $"Lights status changed to {_data}."; case EVT_DATA_TEMPERATURE: { byte[] raw = BitConverter.GetBytes(_data.Value); return $"Temperature, motor={(sbyte)raw[1]}C, controller={(sbyte)raw[0]}C."; } case EVT_DATA_THERMAL_LIMITING: if (_data.Value != 0) { Level = LogLevel.Warning; return "Thermal limiting activated, reducing power."; } else { return "Thermal limiting deactivated."; } case EVT_DATA_SPEED_LIMITING: if (_data.Value != 0) { return "Speed limiting activated."; } else { return "Speed limiting deactivated."; } case EVT_DATA_MAX_CURRENT_ADC_REQUEST: return $"Requesting to configure max current on motor controller mcu, adc={_data}."; case EVT_DATA_MAX_CURRENT_ADC_RESPONSE: return $"Max current configured on motor controller mcu, response was adc={_data}."; case EVT_DATA_MAIN_LOOP_TIME: return $"Main loop, interval={_data}ms."; case EVT_DATA_THROTTLE_ADC: return $"Throttle adc, value={_data}."; case EVT_DATA_LVC_LIMITING: if (_data.Value != 0) { return $"Low voltage limiting activated, voltage={(_data / 100f):0.0}"; } else { return "Low voltage limiting deactivated."; } case EVT_DATA_SHIFT_SENSOR: if (_data.Value != 0) { return $"Shift sensor power ramp started."; } else { return $"Shift sensor power ramp ended."; } case EVT_DATA_BBSHD_THERMISTOR: if (_data.Value != 0) { return "BBSHD motor with PTC thermistor detected."; } else { return "BBSHD motor with NTC thermistor detected."; } case EVT_DATA_VOLTAGE: return $"Battery voltage reading, value={_data / 100f}V."; case EVT_DATA_VOLTAGE_CALIBRATION: return $"Battery voltage calibration updated, adc_steps_per_volt={_data / 100f}."; case EVT_DATA_TORQUE_ADC: return $"Torque adc, value={_data}."; case EVT_DATA_TORQUE_ADC_CALIBRATED: return $"Torque sensor calibrated, adc_bias={_data}."; } if (_data.HasValue) { return $"Unknown ({_event}, value={_data.Value})"; } return $"Unknown ({_event})"; } } } ================================================ FILE: src/tool/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace BBSFW.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool UseFreedomUnits { get { return ((bool)(this["UseFreedomUnits"])); } set { this["UseFreedomUnits"] = value; } } } } ================================================ FILE: src/tool/Properties/Settings.settings ================================================  False ================================================ FILE: src/tool/View/AssistLevelCruiseView.xaml ================================================ ================================================ FILE: src/tool/View/AssistLevelCruiseView.xaml.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BBSFW.View { /// /// Interaction logic for AssistLevelCruiseView.xaml /// public partial class AssistLevelCruiseView : UserControl { public AssistLevelCruiseView() { InitializeComponent(); } } } ================================================ FILE: src/tool/View/AssistLevelPasView.xaml ================================================ Allow the use of throttle while in this assist level. Override configured assist level cadence limit to 100% when power requested by throttle action surpasses power set by pedal assist level. Override configured assist level speed limit to 100% when power requested by throttle action surpasses power set by pedal assist level. ================================================ FILE: src/tool/View/AssistLevelPasView.xaml.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BBSFW.View { /// /// Interaction logic for AssistLevelPasView.xaml /// public partial class AssistLevelPasView : UserControl { public AssistLevelPasView() { InitializeComponent(); } } } ================================================ FILE: src/tool/View/AssistLevelThrottleView.xaml ================================================ ================================================ FILE: src/tool/View/AssistLevelThrottleView.xaml.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BBSFW.View { /// /// Interaction logic for AssistLevelThrottleView.xaml /// public partial class AssistLevelThrottleView : UserControl { public AssistLevelThrottleView() { InitializeComponent(); } } } ================================================ FILE: src/tool/View/AssistLevelsView.xaml ================================================ ================================================ FILE: src/tool/View/AssistLevelsView.xaml.cs ================================================ using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BBSFW.View { /// /// Interaction logic for AssistLevelsView.xaml /// public partial class AssistLevelsView : UserControl { public AssistLevelsView() { InitializeComponent(); } } } ================================================ FILE: src/tool/View/CalibrationView.xaml ================================================