diff --git a/MOC3041.md b/MOC3041.md
index ec95e4e..24d8b9b 100644
--- a/MOC3041.md
+++ b/MOC3041.md
@@ -26,7 +26,7 @@ To test an MOC3041 optoisolator (a zero-crossing triac driver) with low voltage,
```mermaid
graph TD
- A[5V DC] -- 220Ω --|Pin 1| B(MOC3041 LED Anode)
+ A[5V DC] -- 220r --|Pin 1| B(MOC3041 LED Anode)
B --|Pin 2| C(GND)
subgraph Output Side (Triac)
diff --git a/OpenSky/.gitmodules b/OpenSky/.gitmodules
new file mode 100644
index 0000000..48e3e39
--- /dev/null
+++ b/OpenSky/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "arch/cc251x/bootloader"]
+ path = arch/cc251x/bootloader
+ url = https://github.com/fishpepper/OpenSky_BL.git
diff --git a/OpenSky/.travis.sh b/OpenSky/.travis.sh
new file mode 100755
index 0000000..78ac4d0
--- /dev/null
+++ b/OpenSky/.travis.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+touch .i_know_what_i_am_doing
+REVISION=$(git rev-parse --short HEAD)
+make clean
+make
diff --git a/OpenSky/.travis.yml b/OpenSky/.travis.yml
new file mode 100644
index 0000000..9b6520e
--- /dev/null
+++ b/OpenSky/.travis.yml
@@ -0,0 +1,47 @@
+sudo: required
+dist: trusty
+env:
+ - TARGET=D4RII
+ - TARGET=VD5M
+ - TARGET=USKY
+ - TARGET=TINYFISH
+ - TARGET=AFRX
+ - TARGET=RASP
+
+addons:
+ apt_packages:
+ - lib32bz2-1.0
+ - lib32ncurses5
+ - lib32stdc++6
+ - gcc-arm-linux-gnueabi
+ - gcc-multilib
+ - libc-dev
+ - srecord
+# - sdcc
+# - sdcc-libraries
+
+cache:
+ directories:
+ - $HOME/gcc-arm-none-eabi-5_4-2016q2
+ - $HOME/sdcc-3.3.0
+
+before_install:
+ - export GCC_DIR=$HOME/gcc-arm-none-eabi-5_4-2016q2
+ - export GCC_ARCHIVE=$HOME/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2
+ - export GCC_URL=https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2
+ - if [ ! -e $GCC_DIR/bin/arm-none-eabi-g++ ]; then wget $GCC_URL -O $GCC_ARCHIVE; tar xfj $GCC_ARCHIVE -C $HOME; fi
+ - export PATH=$PATH:$GCC_DIR/bin
+ - export TOOLROOT=$GCC_DIR/bin
+ - export SDCC_ARCHIVE=sdcc-3.3.0-i386-unknown-linux2.5.tar.bz2
+ - export SDCC_URL=https://master.dl.sourceforge.net/project/sdcc/sdcc-linux-x86/3.3.0/$SDCC_ARCHIVE
+ - if [ ! -e $HOME/sdcc-3.3.0/bin ]; then wget $SDCC_URL -O $SDCC_ARCHIVE; tar xjf $SDCC_ARCHIVE -C $HOME; fi
+ - export PATH=$PATH:$HOME/sdcc-3.3.0/bin
+
+install:
+ - cd $TRAVIS_BUILD_DIR
+ - chmod +x .travis.sh
+
+language: c
+compiler: gcc
+
+script: ./.travis.sh
diff --git a/OpenSky/LICENSE b/OpenSky/LICENSE
new file mode 100644
index 0000000..733c072
--- /dev/null
+++ b/OpenSky/LICENSE
@@ -0,0 +1,675 @@
+ 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.
+
+ {one line to give the program's name and a brief idea of what it does.}
+ Copyright (C) {year} {name of author}
+
+ 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:
+
+ {project} Copyright (C) {year} {fullname}
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
diff --git a/OpenSky/Makefile b/OpenSky/Makefile
new file mode 100644
index 0000000..8501528
--- /dev/null
+++ b/OpenSky/Makefile
@@ -0,0 +1,107 @@
+#select target. supported: {VD5M, D4RII, USKY, TINYFISH, AFRX, RASP}
+TARGET ?= USKY
+
+ASFLAGS = -g
+ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
+SRC_DIR = $(ROOT)/src
+INCLUDE_DIRS = $(SRC_DIR)
+
+GENERIC_SRCS = $(wildcard $(SRC_DIR)/*.c)
+GENERIC_HEADERS = $(GENERIC_SRCS:.c=.h)
+
+
+
+#a special file can trigger the use of a fixed id (see storage.c)
+#i use this during development to avoid uneccessary re-binding for vd5m targets
+ifneq ($(wildcard .use_fixed_id),)
+CFLAGS += -DFRSKY_USE_FIXED_ID
+endif
+
+OBJECT_DIR := $(ROOT)/obj
+TARGET_LC := $(shell echo $(TARGET) | tr '[:upper:]' '[:lower:]')
+TARGET_DIR := $(ROOT)/board/$(TARGET_LC)
+TARGET_MAKEFILE := $(TARGET_DIR)/target.mk
+CC251X_BL_DIR := arch/cc251x/bootloader
+
+RESULT ?= opensky_$(notdir $(TARGET_LC))
+
+## V : Set verbosity level based on the V= parameter
+## V=0 Low
+## V=1 High
+export AT := @
+
+ifndef V
+export V0 :=
+export V1 := $(AT)
+export STDOUT :=
+else ifeq ($(V), 0)
+export V0 := $(AT)
+export V1 := $(AT)
+export STDOUT:= "> /dev/null"
+export MAKE := $(MAKE) --no-print-directory
+else ifeq ($(V), 1)
+export V0 :=
+export V1 :=
+export STDOUT :=
+endif
+
+all : git_submodule_init ack_disclaimer board
+
+# verifying that the git submodule for the cc2510 bootloader was initialized
+git_submodule_init :
+ @if [ ! -f $(CC251X_BL_DIR)/Makefile ]; then git submodule init $(CC251X_BL_DIR) && git submodule update $(CC251X_BL_DIR); fi
+
+ifneq ($(wildcard $(TARGET_MAKEFILE)),)
+ #fine, target exists
+ include $(TARGET_MAKEFILE)
+ include $(ARCH_MAKEFILE)
+else
+ #does not exist
+ $(error UNSUPPORTED Target ($(TARGET)) given. could not find makefile at $(TARGET_MAKEFILE). aborting)
+endif
+
+ack_disclaimer :
+ifeq ($(wildcard .i_know_what_i_am_doing),)
+ @echo "###############################################"
+ @echo "# WARNING: #"
+ @echo "#=============================================#"
+ @echo "# THIS SOFTWARE IS FOR EDUCATIONAL USE ONLY #"
+ @echo "# #"
+ @echo "# BAD things could happen if you use this #"
+ @echo "# code to control real planes/quadrocopters! #"
+ @echo "# #"
+ @echo "# It is meant to be used on small indoor toys #"
+ @echo "# #"
+ @echo "# Using this code will probably void the FCC #"
+ @echo "# compliance of your RX and might void #"
+ @echo "# transmission laws depending of your country #"
+ @echo "# #"
+ @echo "# I AM NOT RESPONSIBLE FOR ANY DAMAGE or #"
+ @echo "# INJURIES CAUSED BY USING THIS CODE! #"
+ @echo "###############################################"
+ @echo ""
+
+ @while [ -z "$$CONTINUE" ]; do \
+ read -r -p "Do you accept the disclaimer? [y/N] : " CONTINUE; \
+ done ; \
+ [ $$CONTINUE = "y" ] || [ $$CONTINUE = "Y" ] || (echo "\ndisclaimer not accepted. will exit now."; echo ""; exit 1;)
+
+ @echo "fine. you know what you are doing. will build now"
+ @touch .i_know_what_i_am_doing
+endif
+
+all : stylecheck board
+
+stylecheck: $(GENERIC_SRCS) $(GENERIC_HEADERS) $(ARCH_SRCS) $(ARCH_HEADERS)
+ ./stylecheck/cpplint.py \
+ --filter=-build/include,-build/storage_class,-readability/casting,-runtime/arrays \
+ --extensions="h,c" --root=src --linelength=100 $(GENERIC_HEADERS) $(GENERIC_SRCS) || true
+ ./stylecheck/cpplint.py \
+ --filter=-build/include,-build/storage_class,-readability/casting,-runtime/arrays \
+ --extensions="h,c" --root=$(ARCH_DIR) --linelength=100 $(ARCH_HEADERS) $(ARCH_SRCS) || true
+
+
+git_version:
+ git log -n 1 --format=format:"#define GIT_COMMIT \"%h\"%n" HEAD > $@.h
+
+.PHONY: git_version ack_disclaimer git_submodule_init stylecheck
diff --git a/OpenSky/OpenSky.config b/OpenSky/OpenSky.config
new file mode 100644
index 0000000..8cec188
--- /dev/null
+++ b/OpenSky/OpenSky.config
@@ -0,0 +1 @@
+// ADD PREDEFINED MACROS HERE!
diff --git a/OpenSky/OpenSky.creator b/OpenSky/OpenSky.creator
new file mode 100644
index 0000000..e94cbbd
--- /dev/null
+++ b/OpenSky/OpenSky.creator
@@ -0,0 +1 @@
+[General]
diff --git a/OpenSky/OpenSky.files b/OpenSky/OpenSky.files
new file mode 100644
index 0000000..a222f0b
--- /dev/null
+++ b/OpenSky/OpenSky.files
@@ -0,0 +1,546 @@
+board/d4rii/assert.c
+board/d4rii/cc25xx.c
+board/d4rii/cc25xx.h
+board/d4rii/clocksource.c
+board/d4rii/clocksource.h
+board/d4rii/debug.h
+board/d4rii/delay.c
+board/d4rii/delay.h
+board/d4rii/dma.c
+board/d4rii/dma.h
+board/d4rii/failsafe.c
+board/d4rii/failsafe.h
+board/d4rii/frsky.c
+board/d4rii/frsky.h
+board/d4rii/hal_cc25xx.c
+board/d4rii/hal_cc25xx.h
+board/d4rii/hal_clocksource.c
+board/d4rii/hal_clocksource.h
+board/d4rii/hal_defines.h
+board/d4rii/hal_delay.c
+board/d4rii/hal_delay.h
+board/d4rii/hal_dma.c
+board/d4rii/hal_dma.h
+board/d4rii/hal_io.c
+board/d4rii/hal_io.h
+board/d4rii/hal_led.c
+board/d4rii/hal_led.h
+board/d4rii/hal_spi.c
+board/d4rii/hal_spi.h
+board/d4rii/hal_timeout.c
+board/d4rii/hal_timeout.h
+board/d4rii/hal_uart.c
+board/d4rii/hal_uart.h
+board/d4rii/hal_wdt.c
+board/d4rii/hal_wdt.h
+board/d4rii/io.c
+board/d4rii/io.h
+board/d4rii/led.h
+board/d4rii/m.c
+board/d4rii/main.c
+board/d4rii/main.h
+board/d4rii/Makefile
+board/d4rii/config.h
+board/d4rii/ppm.c
+board/d4rii/ppm.h
+board/d4rii/spi.c
+board/d4rii/spi.h
+board/d4rii/storage.c
+board/d4rii/storage.h
+board/d4rii/timeout.c
+board/d4rii/timeout.h
+board/d4rii/uart.c
+board/d4rii/uart.h
+board/d4rii/wdt.c
+board/d4rii/wdt.h
+board/vd5m/hal_cc25xx.h
+board/vd5m/hal_clocksource.c
+board/vd5m/hal_clocksource.h
+board/vd5m/hal_defines.h
+board/vd5m/hal_delay.c
+board/vd5m/hal_delay.h
+board/vd5m/hal_dma.c
+board/vd5m/hal_dma.h
+board/vd5m/hal_io.c
+board/vd5m/hal_led.h
+board/vd5m/hal_spi.c
+board/vd5m/hal_spi.h
+board/vd5m/hal_timeout.c
+board/vd5m/hal_timeout.h
+board/vd5m/hal_uart.c
+board/vd5m/hal_wdt.c
+board/vd5m/hal_wdt.h
+driver/stm32f10x/core/core_cm3.c
+driver/stm32f10x/core/core_cm3.h
+driver/stm32f10x/device/startup_stm32f10x.c
+driver/stm32f10x/device/stm32f10x.h
+driver/stm32f10x/device/stm32f10x_conf.h
+driver/stm32f10x/device/system_stm32f10x.c
+driver/stm32f10x/device/system_stm32f10x.h
+driver/stm32f10x/peripheral_lib/inc/misc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_adc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_bkp.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_can.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_cec.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_crc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_dac.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_dbgmcu.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_dma.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_exti.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_flash.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_fsmc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_gpio.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_i2c.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_iwdg.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_pwr.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_rcc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_rtc.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_sdio.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_spi.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_tim.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_usart.h
+driver/stm32f10x/peripheral_lib/inc/stm32f10x_wwdg.h
+driver/stm32f10x/peripheral_lib/src/misc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_adc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_bkp.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_can.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_cec.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_crc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_dac.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_dbgmcu.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_dma.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_exti.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_flash.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_fsmc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_gpio.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_i2c.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_iwdg.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_pwr.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_rcc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_rtc.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_sdio.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_spi.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_tim.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_usart.c
+driver/stm32f10x/peripheral_lib/src/stm32f10x_wwdg.c
+old/stm32/STM32-Template/Library/ff9/src/option/cc932.c
+old/stm32/STM32-Template/Library/ff9/src/option/cc936.c
+old/stm32/STM32-Template/Library/ff9/src/option/cc949.c
+old/stm32/STM32-Template/Library/ff9/src/option/cc950.c
+old/stm32/STM32-Template/Library/ff9/src/option/ccsbcs.c
+old/stm32/STM32-Template/Library/ff9/src/option/syscall.c
+old/stm32/STM32-Template/Library/ff9/src/diskio.h
+old/stm32/STM32-Template/Library/ff9/src/ff.c
+old/stm32/STM32-Template/Library/ff9/src/ff.h
+old/stm32/STM32-Template/Library/ff9/src/ffconf.h
+old/stm32/STM32-Template/Library/ff9/src/integer.h
+old/stm32/STM32-Template/Library/glcdfont.c
+old/stm32/STM32-Template/Library/i2c.c
+old/stm32/STM32-Template/Library/i2c.h
+old/stm32/STM32-Template/Library/mmcbb.c
+old/stm32/STM32-Template/Library/spi.c
+old/stm32/STM32-Template/Library/spi.h
+old/stm32/STM32-Template/Library/ST7735.c
+old/stm32/STM32-Template/Library/ST7735.h
+old/stm32/STM32-Template/Library/uart.c
+old/stm32/STM32-Template/Library/uart.h
+old/stm32/STM32-Template/Library/uartfc.c
+old/stm32/STM32-Template/Library/xprintf.c
+old/stm32/STM32-Template/Library/xprintf.h
+old/stm32/STM32-Template/stm3210b_eval.c
+old/stm32/STM32-Template/stm3210b_eval.h
+old/stm32/STM32-Template/stm32_eval.h
+old/adc.c
+old/adc.h
+old/apa102.c
+old/apa102.h
+old/clocksource.c
+old/clocksource.h
+old/config.h
+old/debug.h
+old/delay.c
+old/delay.h
+old/dma.c
+old/dma.h
+old/failsafe.c
+old/failsafe.h
+old/flash.c
+old/flash.h
+old/frsky.c
+old/frsky.h
+old/led.h
+old/main.c
+old/main.h
+old/Makefile
+old/portmacros.h
+old/ppm.c
+old/ppm.h
+old/sbus.c
+old/sbus.h
+old/soft_spi.c
+old/soft_spi.h
+old/static_init.h
+old/storage.c
+old/storage.h
+old/timeout.c
+old/timeout.h
+old/uart.c
+old/uart.h
+old/wdt.c
+old/wdt.h
+Makefile
+board/d4rii/hal_storage.h
+board/d4rii/hal_storage.c
+board/vd5m/hal_storage.h
+board/vd5m/hal_storage.c
+board/d4rii/hal_adc.h
+board/d4rii/hal_adc.c
+board/d4rii/adc.h
+board/d4rii/adc.c
+board/vd5m/hal_adc.h
+board/vd5m/hal_adc.c
+board/d4rii/sbus.c
+board/d4rii/sbus.h
+adc.c
+adc.c
+adc.h
+assert.c
+cc25xx.c
+cc25xx.h
+clocksource.c
+clocksource.h
+debug.h
+delay.c
+delay.h
+dma.c
+dma.h
+failsafe.c
+failsafe.h
+frsky.c
+frsky.h
+io.c
+io.h
+led.h
+m.c
+main.c
+main.h
+storage.h
+storage.c
+board/d4rii/d4r_ii_pinout.md
+pin_config.h
+old/sbus.c
+old/sbus.h
+sbus.h
+sbus.c
+board/vd5m/hal_sbus.h
+board/vd5m/hal_sbus.c
+board/d4rii/hal_sbus.c
+board/d4rii/hal_sbus.h
+board/d4rii/pin_config.h
+uart.c
+wdt.h
+wdt.c
+board/d4rii/hal_ppm.h
+board/d4rii/hal_ppm.c
+ppm.h
+ppm.c
+board/vd5m/hal_cc25xx.c
+board/vd5m/hal_clocksource.h
+board/vd5m/hal_clocksource.c
+board/vd5m/hal_uart.h
+uart.h
+board/vd5m/hal_timeout.h
+board/vd5m/hal_timeout.c
+board/vd5m/hal_ppm.c
+board/vd5m/hal_ppm.h
+board/vd5m/hal_flash.c
+board/vd5m/hal_flash.h
+apa102.c
+apa102.h
+board/vd5m/hal_apa102.c
+board/vd5m/hal_apa102.h
+board/d4rii/hal_apa102.c
+board/d4rii/hal_apa102.h
+soft_spi.h
+soft_spi.c
+board/vd5m/hal_soft_spi.h
+board/d4rii/hal_soft_spi.h
+board/d4rii/hal_soft_spi.c
+board/d4rii/hal_soft_spi.c
+board/vd5m/hal_soft_spi.c
+board/d4rii/hal_soft_serial.h
+board/d4rii/hal_soft_serial.c
+board/d4rii/device/startup_stm32f10x.c
+board/d4rii/device/stm32f10x_conf.h
+board/d4rii/device/stm32f10x.h
+board/d4rii/device/system_stm32f10x.c
+board/d4rii/device/system_stm32f10x.h
+soft_serial.c
+soft_serial.h
+board/d4rii/peripheral_lib/src/stm32f10x_tim.c
+telemetry.c
+telemetry.h
+timeout.h
+timeout.c
+board/vd5m/hal_soft_serial.h
+board/vd5m/hal_soft_serial.c
+debug.c
+board/vd5m/hal_uart.c
+board/vd5m/config.h
+board/vd5m/hal_clocksource.c
+board/vd5m/hal_clocksource.h
+board/vd5m/hal_uart.c
+board/vd5m/hal_uart.h
+arch/cc251x/hal_adc.c
+arch/cc251x/hal_adc.h
+arch/cc251x/hal_soft_serial.c
+arch/cc251x/hal_soft_serial.h
+arch/stm32f1/hal_storage.c
+arch/stm32f1/hal_storage.h
+uart.c
+uart.h
+arch/cc251x/hal_ppm.h
+arch/cc251x/hal_uart.c
+arch/cc251x/hal_uart.h
+arch/cc251x/hal_sbus.c
+arch/cc251x/hal_debug.h
+arch/cc251x/hal_debug.c
+arch/cc251x/hal_defines.h
+arch/cc251x/hal_delay.h
+arch/cc251x/hal_delay.c
+arch/cc251x/hal_sbus.h
+arch/stm32f1/hal_sbus.c
+board/tinyfish/config.h
+board/aff4rx/config.h
+board/usky/config.h
+arch/cc251x/hal_cc25xx.c
+arch/cc251x/hal_cc25xx.h
+arch/stm32f1/hal_debug.c
+arch/stm32f1/hal_debug.h
+arch/stm32f1/hal_uart.c
+arch/stm32f1/hal_uart.h
+arch/stm32f1/hal_soft_serial.h
+arch/stm32f1/hal_soft_serial.c
+arch/stm32f1/hal_sbus.h
+arch/stm32f1/hal_ppm.c
+arch/stm32f1/hal_ppm.h
+arch/cc251x/bootloader/blink_test/main.c
+arch/cc251x/bootloader/default/config.h
+arch/cc251x/bootloader/default_config/config.h
+arch/cc251x/bootloader/stylecheck/cpplint_test_header.h
+arch/cc251x/bootloader/cc25xx.h
+arch/cc251x/bootloader/delay.c
+arch/cc251x/bootloader/delay.h
+arch/cc251x/bootloader/device.h
+arch/cc251x/bootloader/dma.h
+arch/cc251x/bootloader/flash.c
+arch/cc251x/bootloader/flash.h
+arch/cc251x/bootloader/io.c
+arch/cc251x/bootloader/io.h
+arch/cc251x/bootloader/led.h
+arch/cc251x/bootloader/main.c
+arch/cc251x/bootloader/main.h
+arch/cc251x/bootloader/portmacros.h
+arch/cc251x/bootloader/uart.c
+arch/cc251x/bootloader/uart.h
+arch/cc251x/hal_adc.c
+arch/cc251x/hal_adc.h
+arch/cc251x/hal_cc25xx.c
+arch/cc251x/hal_cc25xx.h
+arch/cc251x/hal_clocksource.c
+arch/cc251x/hal_clocksource.h
+arch/cc251x/hal_debug.c
+arch/cc251x/hal_debug.h
+arch/cc251x/hal_defines.h
+arch/cc251x/hal_delay.c
+arch/cc251x/hal_delay.h
+arch/cc251x/hal_dma.c
+arch/cc251x/hal_dma.h
+arch/cc251x/hal_io.c
+arch/cc251x/hal_io.h
+arch/cc251x/hal_led.c
+arch/cc251x/hal_led.h
+arch/cc251x/hal_ppm.c
+arch/cc251x/hal_ppm.h
+arch/cc251x/hal_sbus.c
+arch/cc251x/hal_sbus.h
+arch/cc251x/hal_soft_serial.c
+arch/cc251x/hal_soft_serial.h
+arch/cc251x/hal_spi.c
+arch/cc251x/hal_spi.h
+arch/cc251x/hal_storage.c
+arch/cc251x/hal_storage.h
+arch/cc251x/hal_timeout.c
+arch/cc251x/hal_timeout.h
+arch/cc251x/hal_uart.c
+arch/cc251x/hal_uart.h
+arch/cc251x/hal_wdt.c
+arch/cc251x/hal_wdt.h
+arch/cc251x/portmacros.h
+arch/rasp/hal_adc.c
+arch/rasp/hal_adc.h
+arch/rasp/hal_cc25xx.c
+arch/rasp/hal_cc25xx.h
+arch/rasp/hal_clocksource.h
+arch/rasp/hal_debug.c
+arch/rasp/hal_debug.h
+arch/rasp/hal_defines.h
+arch/rasp/hal_delay.h
+arch/rasp/hal_dma.h
+arch/rasp/hal_io.c
+arch/rasp/hal_io.h
+arch/rasp/hal_led.h
+arch/rasp/hal_ppm.c
+arch/rasp/hal_ppm.h
+arch/rasp/hal_sbus.c
+arch/rasp/hal_sbus.h
+arch/rasp/hal_soft_serial.c
+arch/rasp/hal_soft_serial.h
+arch/rasp/hal_spi.c
+arch/rasp/hal_spi.h
+arch/rasp/hal_storage.c
+arch/rasp/hal_storage.h
+arch/rasp/hal_timeout.c
+arch/rasp/hal_timeout.h
+arch/rasp/hal_uart.c
+arch/rasp/hal_uart.h
+arch/rasp/hal_wdt.c
+arch/rasp/hal_wdt.h
+arch/stm32f1/core/core_cm3.c
+arch/stm32f1/core/core_cm3.h
+arch/stm32f1/device/startup_stm32f10x.c
+arch/stm32f1/device/stm32f10x.h
+arch/stm32f1/device/stm32f10x_conf.h
+arch/stm32f1/device/system_stm32f10x.c
+arch/stm32f1/device/system_stm32f10x.h
+arch/stm32f1/peripheral_lib/inc/misc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_adc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_bkp.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_can.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_cec.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_crc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_dac.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_dbgmcu.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_dma.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_exti.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_flash.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_fsmc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_gpio.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_i2c.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_iwdg.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_pwr.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_rcc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_rtc.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_sdio.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_spi.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_tim.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_usart.h
+arch/stm32f1/peripheral_lib/inc/stm32f10x_wwdg.h
+arch/stm32f1/peripheral_lib/src/misc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_adc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_bkp.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_can.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_cec.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_crc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_dac.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_dbgmcu.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_dma.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_exti.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_flash.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_fsmc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_gpio.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_i2c.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_iwdg.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_pwr.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_rcc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_rtc.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_sdio.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_spi.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_tim.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_usart.c
+arch/stm32f1/peripheral_lib/src/stm32f10x_wwdg.c
+arch/stm32f1/hal_adc.c
+arch/stm32f1/hal_adc.h
+arch/stm32f1/hal_cc25xx.c
+arch/stm32f1/hal_cc25xx.h
+arch/stm32f1/hal_clocksource.c
+arch/stm32f1/hal_clocksource.h
+arch/stm32f1/hal_debug.c
+arch/stm32f1/hal_debug.h
+arch/stm32f1/hal_defines.h
+arch/stm32f1/hal_delay.c
+arch/stm32f1/hal_delay.h
+arch/stm32f1/hal_dma.c
+arch/stm32f1/hal_dma.h
+arch/stm32f1/hal_io.c
+arch/stm32f1/hal_io.h
+arch/stm32f1/hal_led.c
+arch/stm32f1/hal_led.h
+arch/stm32f1/hal_ppm.c
+arch/stm32f1/hal_ppm.h
+arch/stm32f1/hal_sbus.c
+arch/stm32f1/hal_sbus.h
+arch/stm32f1/hal_soft_serial.c
+arch/stm32f1/hal_soft_serial.h
+arch/stm32f1/hal_spi.c
+arch/stm32f1/hal_spi.h
+arch/stm32f1/hal_storage.c
+arch/stm32f1/hal_storage.h
+arch/stm32f1/hal_timeout.c
+arch/stm32f1/hal_timeout.h
+arch/stm32f1/hal_uart.c
+arch/stm32f1/hal_uart.h
+arch/stm32f1/hal_wdt.c
+arch/stm32f1/hal_wdt.h
+board/aff4rx/config.h
+board/d4rii/config.h
+board/rasp/config.h
+board/tinyfish/config.h
+board/tinyfish_test/config.h
+board/usky/config.h
+board/vd5m/config.h
+board/xsr/config.h
+src/adc.c
+src/adc.h
+src/assert.c
+src/assert.h
+src/cc25xx.c
+src/cc25xx.h
+src/clocksource.c
+src/clocksource.h
+src/debug.c
+src/debug.h
+src/delay.c
+src/delay.h
+src/dma.c
+src/dma.h
+src/failsafe.c
+src/failsafe.h
+src/frsky.c
+src/frsky.h
+src/io.c
+src/io.h
+src/led.h
+src/main.c
+src/main.h
+src/ppm.c
+src/ppm.h
+src/sbus.c
+src/sbus.h
+src/soft_serial.c
+src/soft_serial.h
+src/spi.c
+src/spi.h
+src/storage.c
+src/storage.h
+src/telemetry.c
+src/telemetry.h
+src/timeout.c
+src/timeout.h
+src/uart.c
+src/uart.h
+src/wdt.c
+src/wdt.h
+stylecheck/cpplint_test_header.h
+git_version.h
+src/io.c
diff --git a/OpenSky/OpenSky.includes b/OpenSky/OpenSky.includes
new file mode 100644
index 0000000..c549fcd
--- /dev/null
+++ b/OpenSky/OpenSky.includes
@@ -0,0 +1,23 @@
+board/d4rii
+board/vd5m
+src/
+board/xsr
+stylecheck
+board/tinyfish_test
+board/tinyfish
+board/rasp
+arch/stm32f1/peripheral_lib/src
+arch/cc251x
+arch/cc251x/bootloader/default
+board/aff4rx
+.
+arch/stm32f1/peripheral_lib/inc
+board/usky
+arch/cc251x/bootloader/blink_test
+arch/cc251x/bootloader
+arch/stm32f1
+arch/cc251x/bootloader/default_config
+arch/cc251x/bootloader/stylecheck
+arch/stm32f1/core
+arch/rasp
+arch/stm32f1/device
diff --git a/OpenSky/README.md b/OpenSky/README.md
new file mode 100644
index 0000000..8c68acc
--- /dev/null
+++ b/OpenSky/README.md
@@ -0,0 +1,204 @@
+# OpenSky
+
+
+[](https://travis-ci.org/fishpepper/OpenSky)
+
+This is an open source implementation for the pololar frsky protocol using
+a cc25xx transceiver chip. This software can be flashed on a DIY RX,
+a FrSky VD5M, or a FrSky D4R-ii receiver.
+Support for other FrSky receivers could be added. E.g. porting this to a X4R should be really easy.
+
+This custom firmware implementation will give you full 8-Channel SBUS or CPPM output,
+full telemetry (2Channels Analog + RSSI) and much more :)
+
+## Warning
+
+*THIS SOFTWARE IS FOR EDUCATIONAL USE ONLY*
+*DO NOT* use this software to control real planes/quadrocopters.
+
+This is for educational use only, bad things could happen
+if you run this on a real vehicle.
+Its meant to be used on indoor and/or small vehicles.
+
+Using this code will probably void its FCC compliance and might
+void any transmission laws depending on your country!
+
+I AM NOT RESPONSIBLE FOR ANY DAMAGE/INJURIES CAUSED BY USING THIS CODE!
+
+
+Additionally: Do not blame me if you brick your RX during the flash upgrade.
+There is currently no way back to the original stock firmware once you erase/flash the devcie
+with my code.
+
+# Features
+
+* completely open source (compiles with the opensource arm gcc or sdcc compiler)
+* fully compatible to frsky 2-way protocol
+* 8 Channel CPPM output OR digital SBUS output (INVERTED or non-INVERTED mode!)
+* failsafe (constant, stopped ppm output)
+* 2 analog telemetry channels
+* RSSI telemetry
+* builtin APA102 Led control (maps to any a ppm channel)
+
+# Supported platforms
+
+* FrSky VD5M
+* FrSky D4r-ii
+* [DIY uSKY - a tiny 0.4g receiver](http://fishpepper.de/projects/usky/)
+* raspberry pi + cc2500 module (for easy development)
+
+# Debugging
+
+When debug is enabled during build (default for now) you will
+get a vast amount of debug info on the serial port (CH5 on VD5M, CH4 on D4R-ii).
+Hook this up to a 3.3V serial to usb connector in order to see the debug information
+on a terminal
+
+# Connections
+
+The connection depends on the receiver and the firmware configuration (main.h)
+
+## VD5M:
+
+(CH1 is at the same side as the LEDs)
+CH1 = BIND MODE (short to GND on startup to enter bind mode) / hub telemetry input (9600)
+CH2 = ADC0
+CH3 = ADC1
+CH4 = CPPM OUT or SBUS (inverted or non-inverted, see main.h)
+CH5 = Debug UART @115200 8N1 (if compiled with debug enabled)
+
+
+You can connect 6 APA102 LEDs to Pins 2 (P2_1 = APA CLOCK) and 3 (P2_2 = APA DATA).
+NOTE: you can not flash the target as long as the APA leds are connected to P2_1,P2_2!
+
+## D4R-ii
+Servo Port:
+
+CH1 = PPM out (if sbus is disabled)
+CH2 = APA102 DATA
+CH3 = APA102 CLK
+CH4 = Debug UART @115200 8N1 OR non-inverted SBUS (see main.h)
+
+
+Serial Port:
+
+(Pin 1 = left = the same side as the LEDs)
+[1] = GND
+[2] = AD2 input (max 3.3V!)
+[3] = inverted SBUS (if enabled in main.h) or Debug UART if debug on
+[4] = inverted Hub Telemetry (either inverted 9600 baud or inverted sbus baudrate)
+
+
+## rasp
+
+Raspberry Pi V2 CC2500
+
+16 GPIO23 GDO2
+17 VCC VCC
+19 MOSI SI
+21 MISO SO
+23 SCLK SCLK
+25 GND GND
+
+03 GPIO02 LNA (Optional, if your chip have LNA)
+05 GPIO03 PA (Optional, if your chip have PA)
+
+37 GPIO26 BIND (pull up to enter bind mode)
+08 TXD SBUS (output using hardware uart)
+40 GPIO21 PPM (software bit banged, low quality)
+
+
+
+
+
+# BUGS
+
+There are probably thousands of bugs. Again: DO NOT USE THIS ON A REAL PLANE/QUADROCOPTER!
+Please report any bugs!
+
+# Flashing
+
+Depending on your target you will need a programmer or a serial converter to flash the software
+
+## VD5M:
+
+You will need a CC debugger or an arduino flashed with this code in order to program the cc2510:
+https://github.com/fishpepper/CC2510Lib
+(theres a python script to flash the cc2510 in that repo as well)
+
+Alternatively, you can use a raspberry pi to flash. This does not require any voltage dividers:
+https://github.com/jimmyw/CC2510Lib
+
+Connections:
+
+It is handy to mount a 5pin Molex Picoblade connector to the
+5pin ISP connection on the side of the vd5m. This way it is easy
+to upgrade firmware.
+
+ISP Port connection on vd5m
+
+
+(pin 1 is on the same side as CH1-5)
+
+The arduino code is rather slow (>30s) whereas the cc-tool flashes in 1s in fast mode!
+
+Notes on using cc-tool on linux:
+make sure to use the patched version from here:
+https://github.com/dashesy/cc-tool
+(this fix is mandatory, otherwise you get a pipe error msg
+-> https://github.com/dashesy/cc-tool/commit/3ebc61763ff5d0dadbdc2f7163e85ca5d002bb0f)
+
+## D4R-ii
+
+This target can be flashed using either a ST-Link V2 or by using the STM32 serial bootloader.
+
+### ST-Link
+
+Connection:
+
+GND = GND
+SWDIO = R12 (the non-gnd side connected to STM32 pin 34)
+SWDCLK = RP2, pin4 (connected to to STM32 pin 37)
+
+to program the device.
+
+### Serial bootloader
+
+The STM32 series of chips has a ROM based un-brickable bootloader. In order to enter the bootloader
+temporarily short circuit the Jumperpad R19 to enter the boot loader. The D4R-ii has a signal inverter
+on board, thus the serial lines are inverted.
+
+Connect an inverted serial cable to the 4pin connector (FTDI devices can be configured to invert rx and tx using mprog!)
+
+(Pin 1 = left = the same side as the LEDs)
+[1] = GND
+[2] = AD2 = do not connect for flashing
+[3] = inverted TX ---> connect to RX
+[4] = inverted RX ---> connect to TX
+
+
+TODO: add flash command to makefile/doc
+
+# Random notes:
+
+Just in case you need to mount a new antenna: My vd5m came with a 3.5cm antenna wire. However it should be 31.5mm long (1/4 wavelength at 2.4GHz)
+
+
+# Thanks
+
+Thanks to midelic from rcgroups.com for the reverse engineering and
+code for the atmega implementation of the frsky protocol!
+Thanks to holger for the d4r-ii donation ;)
+
diff --git a/OpenSky/arch/cc251x/cc251x.mk b/OpenSky/arch/cc251x/cc251x.mk
new file mode 100644
index 0000000..8e008fd
--- /dev/null
+++ b/OpenSky/arch/cc251x/cc251x.mk
@@ -0,0 +1,129 @@
+
+CC = sdcc
+
+HAL_SRCS := hal_led.c \
+ hal_debug.c \
+ hal_uart.c \
+ hal_clocksource.c \
+ hal_timeout.c \
+ hal_wdt.c \
+ hal_delay.c \
+ hal_dma.c \
+ hal_spi.c \
+ hal_cc25xx.c \
+ hal_io.c \
+ hal_adc.c \
+ hal_storage.c \
+ hal_sbus.c \
+ hal_ppm.c \
+ hal_soft_serial.c
+
+ARCH_SRCS := $(addprefix $(ARCH_DIR)/, $(HAL_SRCS))
+ARCH_HEADERS := $(ARCH_SRCS:.c=.h)
+
+BOARD_SRCS := $(GENERIC_SRCS) \
+ $(ARCH_SRCS)
+
+INCLUDE_DIRS := $(INCLUDE_DIRS) \
+ /usr/share/sdcc/include \
+ $(SRC_DIR) \
+ $(ARCH_DIR) \
+ $(TARGET_DIR)
+
+LDFLAGS_FLASH = --out-fmt-ihx \
+ --code-loc 0x0c00 \
+ --code-size $(FLASH_SIZE) \
+ --xram-loc 0xf000 \
+ --xram-size 0x300 \
+ --iram-size 0x100
+
+#programmer binary
+CC_TOOL ?= cc-tool
+
+CFLAGS += --model-small \
+ --opt-code-speed \
+ $(addprefix -I,$(INCLUDE_DIRS))
+
+ifdef DEBUG
+CFLAGS += --debug
+endif
+
+HEADERS := $(BOARD_SRCS:.c=.h)
+ADB = $(BOARD_SRCS:.c=.adb)
+ASM = $(BOARD_SRCS:.c=.asm)
+LNK = $(BOARD_SRCS:.c=.lnk)
+LST = $(BOARD_SRCS:.c=.lst)
+REL = $(BOARD_SRCS:.c=.rel)
+RST = $(BOARD_SRCS:.c=.rst)
+SYM = $(BOARD_SRCS:.c=.sym)
+
+#we build two flavours:
+# _full : includes the bootloader, use this for initial flashing
+# _update: just the opensky fw, relocated to be stored after the bootloader
+TARGET_FULL = $(OBJECT_DIR)/$(RESULT)_full.hex
+TARGET_UPDATE = $(OBJECT_DIR)/$(RESULT)_update.hex
+TARGET_NO_BL = $(OBJECT_DIR)/$(RESULT)_no_bl.hex
+BL_DIR = arch/cc251x/bootloader
+BL_HEX = bootloader.hex
+
+PCDB = $(PROGS:.hex=.cdb)
+PLNK = $(PROGS:.hex=.lnk)
+PMAP = $(PROGS:.hex=.map)
+PMEM = $(PROGS:.hex=.mem)
+PAOM = $(PROGS:.hex=)
+
+SREC_CAT_FOUND := $(shell command -v srec_cat 2> /dev/null)
+
+TARGET_OBJS = $(addsuffix .rel,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(BOARD_SRCS))))
+TARGET_DEPS = $(addsuffix .d,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(BOARD_SRCS))))
+
+# Search path for standard files
+#vpath %.c ./src
+#vpath %.c ./$(ARCH_DIR)
+
+board: $(TARGET_UPDATE) $(TARGET_FULL)
+
+bootloader:
+ @echo "### Building bootloader ###"
+ $(MAKE) -C $(BL_DIR) \
+ STYLECHECK_DISABLED=1 \
+ FLASH_SIZE=$(FLASH_SIZE) \
+ CONFIG_INCLUDE_DIR=../../../$(TARGET_DIR) \
+ clean all
+
+$(TARGET_FULL): $(TARGET_UPDATE) bootloader
+ @echo "merging bootloader and main code"
+ifndef SREC_CAT_FOUND
+ $(error "could not find srec_cat binary. make sure to install the srecord package")
+else
+ srec_cat -disable_sequence_warnings \
+ $(TARGET_UPDATE) -intel \
+ $(BL_DIR)/$(BL_HEX) -intel \
+ -o $(TARGET_FULL) -intel
+ @echo "done."
+endif
+
+$(TARGET_UPDATE): $(TARGET_OBJS)
+ $(V1) echo Linking: $(TARGET)
+ $(V1) $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $@ $^
+
+# this is just for development, DO NOT flash this for production
+$(TARGET_NO_BL): $(TARGET_OBJS)
+ $(V1) $(CC) $(LDFLAGS_FLASH) $(CFLAGS) --code-loc 0x000 -o $@ $^
+
+$(OBJECT_DIR)/$(TARGET)/%.rel: %.c
+ $(V1) mkdir -p $(dir $@)
+ $(V1) echo "%% $(notdir $<)" "$(STDOUT)" && \
+ $(CC) -c -o $@ $(CFLAGS) $<
+
+clean:
+ $(V1) echo Cleaning: $(TARGET)
+ $(V1) rm -f $(ADB) $(ASM) $(LNK) $(LST) $(TARGET_OBJS) $(RST) $(SYM)
+ $(V1) rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+ $(V1) cd $(BL_DIR) && $(MAKE) clean
+
+flash: $(OUTPUT_FULL)
+ $(CC_TOOL) -f -e -w $(TARGET_FULL)
+
+flash_no_bl: $(OUTPUT_NO_BL)
+ $(CC_TOOL) -f -e -w $(TARGET_NO_BL)
diff --git a/OpenSky/arch/cc251x/hal_adc.c b/OpenSky/arch/cc251x/hal_adc.c
new file mode 100644
index 0000000..a58a917
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_adc.c
@@ -0,0 +1,172 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_adc.h"
+#include "hal_defines.h"
+#include "hal_cc25xx.h"
+#include "portmacros.h"
+#include "config.h"
+#include "hal_dma.h"
+#include "debug.h"
+#include "delay.h"
+#include "wdt.h"
+
+
+// adc results
+__xdata uint16_t hal_adc_data[2];
+
+void hal_adc_init(void) {
+ hal_adc_data[0] = 0;
+ hal_adc_data[1] = 0;
+
+ // pin config -> dir = input
+ PORT2DIR(ADC_PORT) &= ~((1 << ADC1) | (1 << ADC0));
+
+ // set special function ADC for those pins:
+ ADCCFG = (1 << ADC1) | (1 << ADC0);
+
+ // set up adc:
+ // - external vref (avcc)
+ // - 10bit adc
+ // - stop on AIN7
+ ADCCON2 = ADCCON2_SREF_AVDD | ADCCON2_SDIV_10BIT | ADCCON2_SCH_AIN7;
+
+ // full speed, start conversion (bit0+1 always write as 1...)
+ ADCCON1 = ADCCON1_ST | ADCCON1_STSEL_FULL_SPEED | 0b11;
+
+ // configure DMA1 + DMA2:
+ hal_adc_dma_init(1, &hal_adc_data[0], DMA_TRIG_ADC_CH0 + ADC0);
+ hal_adc_dma_init(2, &hal_adc_data[1], DMA_TRIG_ADC_CH0 + ADC1);
+
+ // set pointer to the DMA configuration struct into DMA-channel 1-4
+ // configuration
+ SET_WORD(DMA1CFGH, DMA1CFGL, &hal_dma_config[1]);
+
+ hal_adc_dma_arm();
+
+ // for testing only, do not use under normal use
+#if ADC_DO_TEST
+ adc_test();
+#endif // ADC_DO_TEST
+}
+
+void hal_adc_dma_arm(void) {
+ DMAARM = (DMA_ARM_CH1 | DMA_ARM_CH2);
+}
+
+void hal_adc_process(void) {
+ if (hal_adc_dma_done()) {
+ // THIS OUTPUT BREAKS CONNECTIVITY! USE FOR DEBUGGING ONLY.
+ // fine, arm dma:
+ hal_adc_dma_arm();
+ } else {
+ // oops this should not happen
+ debug_putc('D');
+ // cancel and re arm dma
+ // DMAARM = DMA_ARM_ABORT | (DMA_ARM_CH1 | DMA_ARM_CH2);
+ }
+}
+
+
+void hal_adc_dma_init(uint8_t dma_id, uint16_t __xdata *dest_adr, uint8_t trig) {
+ hal_dma_config[dma_id].PRIORITY = DMA_PRI_LOW; // example used high...
+ hal_dma_config[dma_id].M8 = DMA_M8_USE_7_BITS;
+ hal_dma_config[dma_id].IRQMASK = DMA_IRQMASK_DISABLE;
+ hal_dma_config[dma_id].TRIG = trig;
+ hal_dma_config[dma_id].TMODE = DMA_TMODE_BLOCK;
+ hal_dma_config[dma_id].WORDSIZE = DMA_WORDSIZE_BYTE;
+
+ SET_WORD(hal_dma_config[dma_id].SRCADDRH, hal_dma_config[dma_id].SRCADDRL, &X_ADCL);
+ SET_WORD(hal_dma_config[dma_id].DESTADDRH, hal_dma_config[dma_id].DESTADDRL, dest_adr);
+ hal_dma_config[dma_id].VLEN = DMA_VLEN_USE_LEN;
+
+ SET_WORD(hal_dma_config[dma_id].LENH, hal_dma_config[dma_id].LENL, 2);
+ hal_dma_config[dma_id].SRCINC = DMA_SRCINC_1;
+ hal_dma_config[dma_id].DESTINC = DMA_DESTINC_1;
+}
+
+uint8_t hal_adc_dma_done(void) {
+ return ((DMAIRQ & (DMA_ARM_CH1 | DMA_ARM_CH2)) == (DMA_ARM_CH1 | DMA_ARM_CH2));
+}
+
+uint8_t hal_adc_get_scaled(uint8_t ch) {
+ uint16_t adc_data;
+ // adc data is HHHHHHHHLLLL0000 -> shift >>6 to get 10bit
+ // the cc2510 is _ALWAYS_ outputting data in two's complement format
+ // thus we shift >>7 to get 9 bit two's complement
+ // NOTE: the chip seems to have a bug, in contrast to the datasheet
+ // measuring a signal close to GND seems to deliver negative values (!)
+ // therefore we have to check for negative numbers and set them to zero
+ if (ch == 0) {
+ // convert to 8 bit (see above)
+ adc_data = hal_adc_data[1] >> 7;
+ if (adc_data & (1 << 8)) adc_data = 0; // bugfix: handle negative numbers
+ // return fixed value
+ return adc_data;
+ } else {
+ adc_data = hal_adc_data[0] >> 7;
+ if (adc_data & (1 << 8)) adc_data = 0; // bugfix: handle negative numbers
+ #ifdef ADC1_USE_ACS712
+ // acs712 is connected to ADC1
+ // when powered by 5V we can use a trick
+ // to get a good resolution:
+ // use inverted power inputs to get
+ // 0A = 2.5V
+ // 30A = 0.0V
+ return 255-(adc_data);
+ #else
+ return adc_data;
+ #endif // ADC1_USE_ACS712
+ }
+}
+
+#if ADC_DO_TEST
+void hal_adc_test(void) {
+ debug("adc: running test\n"); debug_flush();
+
+ while (1) {
+ debug("adc: re-arming adc\n"); debug_flush();
+ hal_adc_dma_arm();
+
+ debug("adc: waiting for adc completion\n"); debug_flush();
+ while (!hal_adc_dma_done()) {
+ debug_putc('.');
+ delay_ms(1);
+ }
+ debug("\nadc: done. res[0] = "); debug_flush();
+
+ debug_put_uint16(hal_adc_data[0]>>4);
+ debug_putc('x'); debug_put_hex8(hal_adc_data[0]>>12);
+ debug_put_hex8((hal_adc_data[0]>>4)&0xff);
+
+ debug(", res[1] = "); debug_flush();
+
+ debug_put_uint16(hal_adc_data[1]>>4);
+ debug_putc('x'); debug_put_hex8(hal_adc_data[1]>>12);
+ debug_put_hex8((hal_adc_data[1]>>4)&0xff);
+
+ debug_put_newline();
+
+ delay_ms(100);
+
+ // reset wdt
+ wdt_reset();
+ }
+}
+#endif // ADC_DO_TEST
diff --git a/OpenSky/arch/cc251x/hal_adc.h b/OpenSky/arch/cc251x/hal_adc.h
new file mode 100644
index 0000000..23c4056
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_adc.h
@@ -0,0 +1,41 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_ADC_H_
+#define HAL_ADC_H_
+
+#include
+
+#ifdef ADC_PORT
+ #define ADC_ENABLED
+#endif // ADC_PORT
+
+// adc results
+extern __xdata uint16_t hal_adc_data[2];
+
+void hal_adc_init(void);
+uint8_t hal_adc_get_scaled(uint8_t ch);
+void hal_adc_dma_arm(void);
+void hal_adc_dma_init(uint8_t dma_id, uint16_t __xdata *dest_adr, uint8_t trig);
+uint8_t hal_adc_dma_done(void);
+
+void hal_adc_test(void);
+void hal_adc_process(void);
+
+#endif // HAL_ADC_H_
diff --git a/OpenSky/arch/cc251x/hal_cc25xx.c b/OpenSky/arch/cc251x/hal_cc25xx.c
new file mode 100644
index 0000000..640485e
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_cc25xx.c
@@ -0,0 +1,231 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_cc25xx.h"
+#include "cc25xx.h"
+#include "hal_defines.h"
+#include "hal_dma.h"
+#include "delay.h"
+#include "timeout.h"
+#include "debug.h"
+#include "led.h"
+#include "frsky.h"
+#include
+
+EXTERNAL_MEMORY volatile uint8_t hal_cc25xx_mode;
+
+void hal_cc25xx_init(void) {
+ // set highest prio for ch0 (RF)
+ IP1 |= (1<<0);
+ IP0 |= (1<<0);
+
+
+ hal_cc25xx_mode = CC25XX_MODE_RX;
+
+ // if we support LNA/PA make sure to config the pin as output:
+ #ifdef RF_LNA_PORT
+ PORT2DIR(RF_LNA_PORT) |= (1 << RF_LNA_PIN);
+ PORT2DIR(RF_PA_PORT) |= (1 << RF_PA_PIN);
+ // set default to LNA active
+ RF_PA_DISABLE();
+ RF_LNA_ENABLE();
+ #endif // RF_LNA_PORT
+
+ // if we support Diversity make sure to config the pin as output:
+ #ifdef RF_ANTENNA_SWITCH_PORT
+ PORT2DIR(RF_ANTENNA_SWITCH_PORT) |= (1 << RF_ANTENNA_SWITCH_PIN);
+ // select first antenna
+ RF_ANTENNA_SELECT_A();
+ #endif // RF_ANTENNA_SWITCH_PORT
+
+ // if we support HIGH GAIN mode config pin as output:
+ #ifdef RF_HIGH_GAIN_MODE_PORT
+ PORT2DIR(RF_HIGH_GAIN_MODE_PORT) |= (1 << RF_HIGH_GAIN_MODE_PIN);
+ // enable high gain mode?
+ #ifdef RF_HIGH_GAIN_MODE_ENABLED
+ RF_HIGH_GAIN_MODE_ENABLE();
+ #else
+ RF_HIGH_GAIN_MODE_DISABLE();
+ #endif // RF_HIGH_GAIN_MODE_ENABLED
+ #endif // RF_HIGH_GAIN_MODE_PORT
+
+ // if we support Bypass mode make sure to config the pin as output:
+ #ifdef RF_BYPASS_PORT
+ PORT2DIR(RF_BYPASS_MODE_PORT) |= (1 << RF_BYPASS_MODE_PIN);
+ // set default to Bypass off
+ #ifdef RF_BYPASS_MODE_ENABLED
+ RF_BYPASS_MODE_ENABLE();
+ #else
+ RF_BYPASS_MODE_DISABLE();
+ #endif // RF_BYPASS_MODE_ENABLED
+ #endif // RF_BYPASS_PORT
+}
+
+uint32_t hal_cc25xx_set_antenna(uint8_t id) {
+ // select antenna 0 or 1:
+ #ifdef RF_ANTENA_SWITCH_PORT
+ if (id) {
+ RF_ANTENNA_SELECT_B();
+ } else {
+ RF_ANTENNA_SELECT_A();
+ }
+ #endif // RF_ANTENNA_SWITCH_PORT
+ return id;
+}
+
+void hal_cc25xx_disable_rf_interrupt(void) {
+ IEN2 &= ~(IEN2_RFIE);
+ RFIM = 0;
+}
+
+void hal_cc25xx_enter_rxmode(void) {
+#ifdef RF_LNA_PORT
+ RF_LNA_ENABLE();
+ delay_us(20);
+ RF_PA_DISABLE();
+ delay_us(5);
+#endif // RF_LNA_PORT
+
+ // set up dma for radio--->buffer
+ hal_cc25xx_setup_rf_dma(CC25XX_MODE_RX);
+
+ // configure interrupt for every received packet
+ IEN2 |= (IEN2_RFIE);
+
+ // mask done irq
+ RFIM = (1<<4);
+ // interrupts should be enabled globally already..
+ // skip this! sei();
+}
+
+void hal_cc25xx_enter_txmode(void) {
+#ifdef RF_LNA_PORT
+ RF_LNA_DISABLE();
+ delay_us(20);
+ RF_PA_ENABLE();
+ delay_us(5);
+#endif // RF_LNA_PORT
+
+ // abort ch0
+ DMAARM = DMA_ARM_ABORT | DMA_ARM_CH0;
+ hal_cc25xx_setup_rf_dma(CC25XX_MODE_TX);
+}
+
+void hal_cc25xx_setup_rf_dma(uint8_t mode) {
+ // CPU has priority over DMA
+ // Use 8 bits for transfer count
+ // No DMA interrupt when done
+ // DMA triggers on radio
+ // Single transfer per trigger.
+ // One byte is transferred each time.
+
+ hal_dma_config[0].PRIORITY = DMA_PRI_HIGH;
+ hal_dma_config[0].M8 = DMA_M8_USE_8_BITS;
+ hal_dma_config[0].IRQMASK = DMA_IRQMASK_DISABLE;
+ hal_dma_config[0].TRIG = DMA_TRIG_RADIO;
+ hal_dma_config[0].TMODE = DMA_TMODE_SINGLE;
+ hal_dma_config[0].WORDSIZE = DMA_WORDSIZE_BYTE;
+
+ // store mode
+ hal_cc25xx_mode = mode;
+
+ if (hal_cc25xx_mode == CC25XX_MODE_TX) {
+ // Transmitter specific DMA settings
+ // Source: radioPktBuffer
+ // Destination: RFD register
+ // Use the first byte read + 1
+ // Sets the maximum transfer count allowed (length byte + data)
+ // Data source address is incremented by 1 byte
+ // Destination address is constant
+ SET_WORD(hal_dma_config[0].SRCADDRH, hal_dma_config[0].SRCADDRL, frsky_packet_buffer);
+ SET_WORD(hal_dma_config[0].DESTADDRH, hal_dma_config[0].DESTADDRL, &X_RFD);
+ hal_dma_config[0].VLEN = DMA_VLEN_FIRST_BYTE_P_1;
+ SET_WORD(hal_dma_config[0].LENH, hal_dma_config[0].LENL, (FRSKY_PACKET_LENGTH+1));
+ hal_dma_config[0].SRCINC = DMA_SRCINC_1;
+ hal_dma_config[0].DESTINC = DMA_DESTINC_0;
+ } else {
+ // Receiver specific DMA settings:
+ // Source: RFD register
+ // Destination: radioPktBuffer
+ // Use the first byte read + 3 (incl. 2 status bytes)
+ // Sets maximum transfer count allowed (length byte + data + 2 status bytes)
+ // Data source address is constant
+ // Destination address is incremented by 1 byte for each write
+ SET_WORD(hal_dma_config[0].SRCADDRH, hal_dma_config[0].SRCADDRL, &X_RFD);
+ SET_WORD(hal_dma_config[0].DESTADDRH, hal_dma_config[0].DESTADDRL, frsky_packet_buffer);
+ hal_dma_config[0].VLEN = DMA_VLEN_FIRST_BYTE_P_3;
+ SET_WORD(hal_dma_config[0].LENH, hal_dma_config[0].LENL, (FRSKY_PACKET_LENGTH+3));
+ hal_dma_config[0].SRCINC = DMA_SRCINC_0;
+ hal_dma_config[0].DESTINC = DMA_DESTINC_1;
+ }
+
+ // Save pointer to the DMA configuration struct into DMA-channel 0
+ // configuration registers
+ SET_WORD(DMA0CFGH, DMA0CFGL, &hal_dma_config[0]);
+
+ // frsky_packet_received = 0;
+}
+
+void hal_cc25xx_enable_receive(void) {
+ // start receiving on dma channel 0
+ DMAARM = DMA_ARM_CH0;
+}
+
+
+
+void hal_cc25xx_rf_interrupt(void) __interrupt RF_VECTOR {
+ // clear int flag
+ RFIF &= ~(1<<4);
+
+ // clear general statistics reg
+ S1CON &= ~0x03;
+
+ if (hal_cc25xx_mode == CC25XX_MODE_RX) {
+ // mark as received:
+ frsky_packet_received = 1;
+ // re arm DMA channel 0
+ hal_cc25xx_enable_receive();
+ } else {
+ frsky_packet_sent = 1;
+ }
+}
+
+uint8_t hal_cc25xx_transmission_completed(void) {
+ // this flag is set in the RF isr
+ return (frsky_packet_sent);
+}
+
+
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len) {
+ UNUSED(buffer);
+ UNUSED(len);
+
+ RFST = RFST_STX;
+
+ // start transmitting on dma channel 0
+ DMAARM = DMA_ARM_CH0;
+
+ // mark packet as not sent (will be modified in RF isr):
+ frsky_packet_sent = 0;
+
+ // tricky: this will force an int request and
+ // initiate the actual transmission
+ S1CON |= 0x03;
+}
+
diff --git a/OpenSky/arch/cc251x/hal_cc25xx.h b/OpenSky/arch/cc251x/hal_cc25xx.h
new file mode 100644
index 0000000..04c149c
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_cc25xx.h
@@ -0,0 +1,276 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_CC25XX_H_
+#define HAL_CC25XX_H_
+#include
+#include "hal_defines.h"
+#include "config.h"
+#include
+
+
+#define CC25XX_FIFO FIFO
+
+#define hal_cc25xx_set_register(reg, val) { reg = val; }
+#define hal_cc25xx_strobe(val) { RFST = val; }
+#define hal_cc25xx_get_register(r) (r)
+#define hal_cc25xx_get_register_burst(r) (r)
+
+
+#ifdef RF_LNA_PORT
+ #define RF_LNA_ENABLE() { PORT2BIT(RF_LNA_PORT, RF_LNA_PIN) = RF_LNA_ON_LEVEL; }
+ #define RF_LNA_DISABLE() { PORT2BIT(RF_LNA_PORT, RF_LNA_PIN) = ~RF_LNA_ON_LEVEL; }
+ #define RF_PA_ENABLE() { PORT2BIT(RF_PA_PORT, RF_PA_PIN) = RF_PA_ON_LEVEL; }
+ #define RF_PA_DISABLE() { PORT2BIT(RF_PA_PORT, RF_PA_PIN) = ~RF_PA_ON_LEVEL; }
+#endif // RF_LNA_PORT
+
+#ifdef RF_ANTENNA_SWITCH_PORT
+ #define RF_ANTENNA_SELECT_A() { PORT2BIT(RF_ANTENNA_SWITCH_PORT, RF_ANTENNA_SWITCH_PIN) = RF_ANTENNA_A_LEVEL; }
+ #define RF_ANTENNA_SELECT_B() { PORT2BIT(RF_ANTENNA_SWITCH_PORT, RF_ANTENNA_SWITCH_PIN) = ~RF_ANTENNA_A_LEVEL; }
+#endif // RF_ANTENNA_SWITCH_PORT
+
+#ifdef RF_HIGH_GAIN_MODE_PORT
+ #define RF_HIGH_GAIN_MODE_ENABLE() { \
+ PORT2BIT(RF_HIGH_GAIN_MODE_PORT, RF_HIGH_GAIN_MODE_PIN) = RF_HIGH_GAIN_MODE_ON_LEVEL; }
+ #define RF_HIGH_GAIN_MODE_DISBALE() { \
+ PORT2BIT(RF_HIGH_GAIN_MODE_PORT, RF_HIGH_GAIN_MODE_PIN) = ~RF_HIGH_GAIN_MODE_ON_LEVEL; }
+#endif // RF_HIGH_GAIN_MODE_PORT
+
+#ifdef RF_BYPASS_MODE_PORT
+ #define RF_BYPASS_MODE_ENABLE() { PORT2BIT(RF_BYPASS_MODE_PORT, RF_BYPASS_MODE_PIN) = RF_BYPASS_MODE_ON_LEVEL; }
+ #define RF_BYPASS_MODE_DISABLE() { PORT2BIT(RF_BYPASS_MODE_PORT, RF_BYPASS_MODE_PIN) = ~RF_BYPASS_MODE_ON_LEVEL; }
+#endif // RF_BYPASS_MODE_PORT
+
+uint32_t hal_cc25xx_set_antenna(uint8_t id);
+#define hal_cc25xx_process_packet(packet_received, buffer, maxlen) {}
+
+void hal_cc25xx_init(void);
+#define hal_cc25xx_set_gdo_mode() {}
+void hal_cc25xx_disable_rf_interrupt(void);
+
+#define hal_cc25xx_rx_sleep() { delay_us(1000); }
+#define hal_cc25xx_tx_sleep() { delay_us(900); }
+
+void hal_cc25xx_enter_rxmode(void);
+void hal_cc25xx_enter_txmode(void);
+void hal_cc25xx_setup_rf_dma(uint8_t mode);
+void hal_cc25xx_enable_receive(void);
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len);
+uint8_t hal_cc25xx_transmission_completed(void);
+
+void hal_cc25xx_rf_interrupt(void) __interrupt RF_VECTOR;
+
+#define hal_cc25xx_partnum_valid(p, v) ((p == 0x81) && (v = 0x04))
+
+#define PERCFG_U0CFG (1<<0)
+#define PERCFG_U1CFG (1<<1)
+#define PERCFG_T4CFG (1<<4)
+#define PERCFG_T3CFG (1<<5)
+#define PERCFG_T1CFG (1<<6)
+
+#define IEN0_RFTXRXIE (1<<0)
+#define IEN0_ADCIE (1<<1)
+#define IEN0_URX0IE (1<<2)
+#define IEN0_URX1IE (1<<3)
+#define IEN0_ENCIE (1<<4)
+#define IEN0_STIE (1<<5)
+#define IEN0_EA (1<<7)
+
+// bit 7 - unused
+// bit 6 - unused
+#define PICTL_P2IEN (1<<5)
+#define PICTL_P0IENH (1<<4)
+#define PICTL_P0IENL (1<<3)
+#define PICTL_P2ICON (1<<2)
+#define PICTL_P1ICON (1<<1)
+#define PICTL_P0ICON (1<<0)
+
+#define IEN1_P0IE (1<<5)
+#define IEN1_T4IE (1<<4)
+#define IEN1_T3IE (1<<3)
+#define IEN1_T2IE (1<<2)
+#define IEN1_T1IE (1<<1)
+#define IEN1_DMAIE (1<<0)
+
+#define IEN2_RFIE (1<<0)
+#define IEN2_P2IE (1<<1)
+#define IEN2_UTX0IE (1<<2)
+#define IEN2_UTX1IE (1<<3)
+#define IEN2_P1IE (1<<4)
+#define IEN2_WDTIE (1<<5)
+
+#define U0GCR_ORDER (1<<5)
+#define U0GCR_CPHA (1<<6)
+#define U0GCR_CPOL (1<<7)
+#define U0CSR_TX_BYTE (1<<1)
+
+#define U1GCR_ORDER (1<<5)
+#define U1GCR_CPHA (1<<6)
+#define U1GCR_CPOL (1<<7)
+
+#define UxCSR_RX_ENABLE (1<<6)
+#define UxCSR_RX_BYTE (1<<2)
+#define UxCSR_TX_BYTE (1<<1)
+
+
+#define RFST_SNOP 0x05
+#define RFST_SIDLE 0x04
+#define RFST_STX 0x03
+#define RFST_SRX 0x02
+#define RFST_SCAL 0x01
+#define RFST_SFSTXON 0x00
+// statemachine on cc2510 is different.
+// instead of SF*X we should use SIDLE
+#define RFST_SFTX RFST_SIDLE
+#define RFST_SFRX RFST_SIDLE
+
+// append status
+#define CC2500_PKTCTRL1_APPEND_STATUS (1<<2)
+// crc autoflush
+#define CC2500_PKTCTRL1_CRC_AUTOFLUSH (1<<3)
+// adress checks
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_00 ((0<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_01 ((0<<1) | (1<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_10 ((1<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_11 ((1<<1) | (1<<0))
+
+
+#define CLKCON_TICKSPD_001 (0b00001000)
+#define CLKCON_TICKSPD_010 (0b00010000)
+#define CLKCON_TICKSPD_011 (0b00011000)
+#define CLKCON_TICKSPD_100 (0b00100000)
+#define CLKCON_TICKSPD_101 (0b00101000)
+#define CLKCON_TICKSPD_110 (0b00110000)
+#define CLKCON_TICKSPD_111 (0b00111000)
+#define CLKCON_OSC32K (1<<7)
+
+#define ADCCON2_SREF_INT (0b00<<6)
+#define ADCCON2_SREF_EXT (0b01<<6)
+#define ADCCON2_SREF_AVDD (0b10<<6)
+#define ADCCON2_SREF_EXTDIFF (0b11<<6)
+#define ADCCON2_SDIV_7BIT (0b00<<4)
+#define ADCCON2_SDIV_9BIT (0b01<<4)
+#define ADCCON2_SDIV_10BIT (0b10<<4)
+#define ADCCON2_SDIV_12BIT (0b11<<4)
+#define ADCCON2_SCH_AIN0 (0b0000<<0)
+#define ADCCON2_SCH_AIN1 (0b0001<<0)
+#define ADCCON2_SCH_AIN2 (0b0010<<0)
+#define ADCCON2_SCH_AIN3 (0b0011<<0)
+#define ADCCON2_SCH_AIN4 (0b0100<<0)
+#define ADCCON2_SCH_AIN5 (0b0101<<0)
+#define ADCCON2_SCH_AIN6 (0b0110<<0)
+#define ADCCON2_SCH_AIN7 (0b0111<<0)
+#define ADCCON2_SCH_AIN0AIN1 (0b1000<<0)
+#define ADCCON2_SCH_AIN2AIN3 (0b1001<<0)
+#define ADCCON2_SCH_AIN4AIN5 (0b1010<<0)
+#define ADCCON2_SCH_AIN6AIN7 (0b1011<<0)
+#define ADCCON2_SCH_GND (0b1100<<0)
+#define ADCCON2_SCH_POSVREF (0b1101<<0)
+#define ADCCON2_SCH_TEMP (0b1110<<0)
+#define ADCCON2_SCH_VDD3 (0b1111<<0)
+
+#define ADCCON1_ST (1<<6)
+#define ADCCON1_STSEL_FULL_SPEED (0b01<<4)
+
+#define WDCTL_EN (1<<3)
+#define WDCTL_MODE (1<<2)
+#define WDCTL_INT (0b11)
+#define WDCTL_INT_1S (0b00)
+
+#define FCTL_BUSY (1<<7)
+#define FCTL_SWBUSY (1<<6)
+#define FCTL_WRITE (1<<1)
+#define FCTL_ERASE (1<<0)
+
+
+#define T1CTL_MODE_SUSPEND (0b00<<0)
+#define T1CTL_MODE_FREE_RUNNING (0b01<<0)
+#define T1CTL_MODE_MODULO (0b10<<0)
+#define T1CTL_MODE_UPDOWN (0b11<<0)
+#define T1CTL_DIV_1 (0b00<<2)
+#define T1CTL_DIV_8 (0b01<<2)
+#define T1CTL_DIV_32 (0b10<<2)
+#define T1CTL_DIV_128 (0b11<<2)
+#define T1CTL_OVFIF (1<<4)
+#define T1CTL_CH0_IF (1<<5)
+#define T1CTL_CH1_IF (1<<6)
+#define T1CTL_CH2_IF (1<<7)
+
+
+
+#define T3CTL_MODE_SUSPEND (0b00<<0)
+#define T3CTL_MODE_FREE_RUNNING (0b01<<0)
+#define T3CTL_MODE_MODULO (0b10<<0)
+#define T3CTL_MODE_UPDOWN (0b11<<0)
+#define T3CTL_CLR (1<<2)
+#define T3CTL_OVFIM (1<<3)
+#define T3CTL_START (1<<4)
+#define T3CTL_DIV_1 (0b000<<5)
+#define T3CTL_DIV_2 (0b001<<5)
+#define T3CTL_DIV_4 (0b010<<5)
+#define T3CTL_DIV_8 (0b011<<5)
+#define T3CTL_DIV_16 (0b100<<5)
+#define T3CTL_DIV_32 (0b101<<5)
+#define T3CTL_DIV_64 (0b110<<5)
+#define T3CTL_DIV_128 (0b111<<5)
+
+
+#define T4CTL_MODE_SUSPEND (0b00<<0)
+#define T4CTL_MODE_FREE_RUNNING (0b01<<0)
+#define T4CTL_MODE_MODULO (0b10<<0)
+#define T4CTL_MODE_UPDOWN (0b11<<0)
+#define T4CTL_CLR (1<<2)
+#define T4CTL_OVFIM (1<<3)
+#define T4CTL_START (1<<4)
+#define T4CTL_DIV_1 (0b000<<5)
+#define T4CTL_DIV_2 (0b001<<5)
+#define T4CTL_DIV_4 (0b010<<5)
+#define T4CTL_DIV_8 (0b011<<5)
+#define T4CTL_DIV_16 (0b100<<5)
+#define T4CTL_DIV_32 (0b101<<5)
+#define T4CTL_DIV_64 (0b110<<5)
+#define T4CTL_DIV_128 (0b111<<5)
+
+
+#define T1CCTLx_CAP_NO (0b00<<0)
+#define T1CCTLx_CAP_RISING (0b01<<0)
+#define T1CCTLx_CAP_FALLING (0b10<<0)
+#define T1CCTLx_CAP_BOTH (0b11<<0)
+#define T1CCTLx_MODE_CAPTURE (0<<2)
+#define T1CCTLx_MODE_COMPARE (1<<2)
+#define T1CCTLx_CMP_SET (0b000<<3)
+#define T1CCTLx_CMP_CLEAR (0b001<<3)
+#define T1CCTLx_CMP_TOGGLE (0b010<<3)
+#define T1CCTLx_CMP_SETCLR0 (0b011<<3)
+#define T1CCTLx_CMP_CLRSET0 (0b100<<3)
+#define T1CCTLx_CMP_RES0 (0b101<<3)
+#define T1CCTLx_CMP_RES1 (0b110<<3)
+#define T1CCTLx_CMP_RES2 (0b111<<3)
+#define T1CCTLx_IM (1<<6)
+#define T1CCTLx_CPSEL_RF (1<<7)
+
+
+// add missing defines
+#include
+SFRX(TEST2, 0xDF23);
+SFRX(TEST1, 0xDF24);
+SFRX(TEST0, 0xDF25);
+
+
+#endif // HAL_CC25XX_H_
diff --git a/OpenSky/arch/cc251x/hal_clocksource.c b/OpenSky/arch/cc251x/hal_clocksource.c
new file mode 100644
index 0000000..bfdcb0e
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_clocksource.c
@@ -0,0 +1,50 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_clocksource.h"
+#include "hal_cc25xx.h"
+#include "led.h"
+
+void hal_clocksource_init(void) {
+ // for debugging clocksource problems
+ led_red_on();
+ led_green_on();
+
+ // power up osc (?)
+ SLEEP &= ~CLOCKSOURCE_OSC_PD_BIT;
+ // wait for XOSC stable
+ while (!CLOCKSOURCE_XOSC_STABLE()) {}
+ NOP();
+
+ // start crystal osc as HS clocksource, OSC32 is int rc osc
+ CLKCON = 0x80;
+
+ // wait for selection to be active
+ while (!CLOCKSOURCE_XOSC_STABLE()) {}
+ NOP();
+
+ // power down the unused oscillator
+ SLEEP |= CLOCKSOURCE_OSC_PD_BIT;
+
+
+ // for debugging clocksource problems
+ led_red_off();
+ led_green_off();
+}
+
diff --git a/OpenSky/arch/cc251x/hal_clocksource.h b/OpenSky/arch/cc251x/hal_clocksource.h
new file mode 100644
index 0000000..4840356
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_clocksource.h
@@ -0,0 +1,47 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_CLOCKSOURCE_H_
+#define HAL_CLOCKSOURCE_H_
+
+#include "hal_cc25xx.h"
+
+void hal_clocksource_init(void);
+
+// bit mask used to check the stability of XOSC
+#define CLOCKSOURCE_XOSC_STABLE_BIT 0x40
+// bit mak used to check the stability of the High-frequency RC oscillator
+#define CLOCKSOURCE_HFRC_STB_BIT 0x20
+// bit maks used to power down system clock oscillators
+#define CLOCKSOURCE_OSC_PD_BIT 0x04
+
+// bit mask used to control the system clock oscillator
+#define CLOCKSOURCE_MAIN_OSC_BITS 0x7F
+
+// bit mask used to select/check the system clock oscillator
+#define CLOCKSOURCE_OSC_BIT 0x40
+
+// macros to check for stable oscs:
+#define CLOCKSOURCE_HFRC_OSC_STABLE() (SLEEP & (CLOCKSOURCE_HFRC_STB_BIT))
+#define CLOCKSOURCE_XOSC_STABLE() (SLEEP & (CLOCKSOURCE_XOSC_STABLE_BIT))
+
+#define CLOCKSOURCE_XOSC 0
+#define CLOCKSOURCE_HFRC 1
+
+#endif // HAL_CLOCKSOURCE_H_
diff --git a/OpenSky/arch/cc251x/hal_debug.c b/OpenSky/arch/cc251x/hal_debug.c
new file mode 100644
index 0000000..cb9807b
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_debug.c
@@ -0,0 +1,160 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_debug.h"
+#include "hal_defines.h"
+
+void hal_debug_init(void) {
+ __xdata union hal_uart_config_t uart_config;
+
+#ifndef DEBUG_UART
+#error "ERROR: DEBUG_UART not defined"
+#endif // DEBUG_UART
+
+#if DEBUG_UART == USART0_P0
+ // USART0 use ALT1 -> Clear flag -> Port P0_3 = TX
+ PERCFG &= ~(PERCFG_U0CFG);
+
+ // configure pin P0_3 (TX) as special function:
+ P0SEL |= (1<<3);
+ // set P0_5 as normal IO
+ P1SEL &= ~(1<<5);
+
+ // make tx pin output:
+ P0DIR |= (1<<3);
+#elif DEBUG_UART == USART0_P1
+ // USART0 use ALT2 -> Set flag -> Port P1_5 = TX
+ PERCFG |= (PERCFG_U0CFG);
+
+ // configure pin P1_5 (TX) as special function
+ P1SEL |= (1<<5);
+ // set P0_3 as normal IO
+ P0SEL &= ~(1<<3);
+
+ // make tx pin output:
+ P1DIR |= (1<<5);
+#elif DEBUG_UART == USART1_P0
+ // USART1 use ALT1 -> Clear flag -> Port P0_4 = TX
+ PERCFG &= ~(PERCFG_U1CFG);
+
+ // USART1 has priority when USART0 is also enabled
+ P2DIR = (P2DIR & 0x3F) | 0b01000000;
+
+ // configure pin P0_4 special function:
+ P0SEL |= (1<<4);
+ // configure P1_6 as normal IO
+ P1SEL &= ~(1<<6);
+
+ // make sure all P1 pins switch to normal GPIO
+ // P1SEL &= ~(0xF0);
+
+ // make tx pin output:
+ P0DIR |= (1<<4);
+#else
+ #error "ERROR: UNSUPPORTED DEBUG UART"
+#endif // DEBUG_UART == ...
+
+ // this assumes cpu runs from XOSC (26mhz) !
+ // set baudrate
+#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
+ U0BAUD = CC2510_BAUD_M_115200;
+ U0GCR = (U0GCR & ~0x1F) | (CC2510_BAUD_E_115200);
+#else
+ U1BAUD = CC2510_BAUD_M_115200;
+ U1GCR = (U1GCR & ~0x1F) | (CC2510_BAUD_E_115200);
+#endif // DEBUG_UART == ...
+
+ // set up config
+ uart_config.bit.START = 0; // startbit level = low
+ uart_config.bit.STOP = 1; // stopbit level = high
+ uart_config.bit.SPB = 0; // 1 stopbit
+ uart_config.bit.PARITY = 0; // no parity
+ uart_config.bit.BIT9 = 0; // 8bit
+ uart_config.bit.D9 = 0; // 8 Bits
+ uart_config.bit.FLOW = 0; // no hw flow control
+ uart_config.bit.ORDER = 0; // lsb first
+ hal_debug_set_mode(&uart_config);
+
+ // enable interrupts:
+ sei();
+}
+
+static void hal_debug_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg) {
+#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
+ // enable uart mode
+ U0CSR |= 0x80;
+
+ // store config to UxUCR register
+ U0UCR = cfg->byte & (0x7F);
+
+ // store config to U1GCR: (msb/lsb)
+ if (cfg->bit.ORDER) {
+ U0GCR |= U0GCR_ORDER;
+ } else {
+ U0GCR &= ~U0GCR_ORDER;
+ }
+
+ // interrupt prio to 0 (0..3=highest)
+ IP0 &= ~(1<<2);
+ IP1 &= ~(1<<2);
+#else
+ // enable uart mode
+ U1CSR |= 0x80;
+
+ // store config to UxUCR register
+ U1UCR = cfg->byte & (0x7F);
+
+ // store config to U1GCR: (msb/lsb)
+ if (cfg->bit.ORDER) {
+ U1GCR |= U1GCR_ORDER;
+ } else {
+ U1GCR &= ~U1GCR_ORDER;
+ }
+ // interrupt prio to 0 (0..3=highest)
+ IP0 &= ~(1<<3);
+ IP1 &= ~(1<<3);
+#endif // DEBUG_UART == ...
+}
+
+
+void hal_debug_start_transmission(uint8_t ch) {
+#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
+ // clear flags
+ UTX0IF = 0;
+ U0CSR &= ~UxCSR_TX_BYTE;
+
+ // enable TX int:
+ IEN2 |= (IEN2_UTX0IE);
+
+ // send this char
+ U0DBUF = ch;
+#else
+ // clear flags
+ UTX1IF = 0;
+ U1CSR &= ~UxCSR_TX_BYTE;
+
+ // enable TX int:
+ IEN2 |= (IEN2_UTX1IE);
+
+ // send this char
+ U1DBUF = ch;
+#endif // DEBUG_UART == ...
+}
+
+
diff --git a/OpenSky/arch/cc251x/hal_debug.h b/OpenSky/arch/cc251x/hal_debug.h
new file mode 100644
index 0000000..41c4a16
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_debug.h
@@ -0,0 +1,53 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DEBUG_H_
+#define HAL_DEBUG_H_
+
+#include "hal_cc25xx.h"
+#include "hal_uart.h"
+#include
+
+void hal_debug_init(void);
+void hal_debug_start_transmission(uint8_t ch);
+
+#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
+ #define hal_debug_int_enabled() (IEN2 & (IEN2_UTX0IE))
+#else
+ #define hal_debug_int_enabled() (IEN2 & (IEN2_UTX1IE))
+#endif // DEBUG_UART == ...
+#define hal_debug_int_enable() { sei(); }
+#define hal_debug_int_disable() { cli(); }
+
+static void hal_debug_set_mode(__xdata union hal_uart_config_t *cfg);
+#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
+ #define DEBUG_ISR(void) hal_uart_tx_interrupt(void) __interrupt UTX0_VECTOR
+ #define HAL_DEBUG_ISR_FLAG_SET() (1)
+ #define HAL_DEBUG_ISR_CLEAR_FLAG() { UTX0IF = 0; }
+ #define HAL_DEBUG_ISR_DISABLE() { IEN2 &= ~(IEN2_UTX0IE); }
+ #define HAL_DEBUG_TX_DATA(data) { U0DBUF = data; }
+#else
+ #define DEBUG_ISR(void) hal_uart_tx_interrupt(void) __interrupt UTX1_VECTOR
+ #define HAL_DEBUG_ISR_FLAG_SET() (1)
+ #define HAL_DEBUG_ISR_CLEAR_FLAG() { UTX1IF = 0; }
+ #define HAL_DEBUG_ISR_DISABLE() { IEN2 &= ~(IEN2_UTX1IE); }
+ #define HAL_DEBUG_TX_DATA(data) { U1DBUF = data; }
+#endif // DEBUG_UART == ...
+
+#endif // HAL_DEBUG_H_
diff --git a/OpenSky/arch/cc251x/hal_defines.h b/OpenSky/arch/cc251x/hal_defines.h
new file mode 100644
index 0000000..e63dafc
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_defines.h
@@ -0,0 +1,29 @@
+#ifndef __HAL_DEFINES_H__
+#define __HAL_DEFINES_H__
+
+#define EXTERNAL_MEMORY __xdata
+#define EXTERNAL_DATA __data
+#define inline
+
+#define sei() { IEN0 |= IEN0_EA; }
+#define cli() { IEN0 &= ~IEN0_EA; }
+
+#ifndef NOP
+ #define NOP() { __asm nop __endasm; }
+#endif
+#define NOP45() { NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
+
+#define HI(a) (uint8_t) ((uint16_t)(a) >> 8 )
+#define LO(a) (uint8_t) (uint16_t)(a)
+#define SET_WORD(H, L, val) { (H) = HI(val); (L) = LO(val); }
+// necessary for timer registers. todo: check if necessary for others as well...
+#define SET_WORD_LO_FIRST(H, L, val) {(L) = LO(val); (H) = HI(val); }
+
+#define UNUSED(x) (void)(x);
+
+#define USART0_P0 0
+#define USART0_P1 1
+#define USART1_P0 2
+#define USART1_P1 3
+
+#endif // __HAL_DEFINES_H__
diff --git a/OpenSky/arch/cc251x/hal_delay.c b/OpenSky/arch/cc251x/hal_delay.c
new file mode 100644
index 0000000..4d01282
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_delay.c
@@ -0,0 +1,58 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_delay.h"
+
+// busy wait delay loop. not 100% accurate
+void hal_delay_ms(uint16_t ms) {
+ #define DELAY_MS_LOOP_A 86
+ #define DELAY_MS_LOOP_B 30
+
+ while (ms--) {
+ // this asm snippet gives us roughly 1ms delay:
+ __asm
+ mov r1, #DELAY_MS_LOOP_A
+ 00000$: // delay_ms_loop_outer
+ dec r1
+ mov a, r1
+ jz 00002$
+ mov r2, #DELAY_MS_LOOP_B
+ 00001$: // delay_ms_loop_inner
+ dec r2
+ mov a, r2
+ jz 00000$
+ sjmp 00001$
+ 00002$: // delay_ms_done
+ __endasm;
+ }
+}
+
+// busy wait delay loop
+// this is more or less accurate
+void hal_delay_us(uint16_t us) {
+ #define DELAY_US_LOOP 1
+
+ while (us--) {
+ __asm
+ nop
+ nop
+ nop
+ __endasm;
+ }
+}
diff --git a/OpenSky/arch/cc251x/hal_delay.h b/OpenSky/arch/cc251x/hal_delay.h
new file mode 100644
index 0000000..75be9ab
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_delay.h
@@ -0,0 +1,28 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DELAY_H_
+#define HAL_DELAY_H_
+#include
+
+void hal_delay_ms(uint16_t ms);
+void hal_delay_us(uint16_t us);
+#define hal_delay_45nop(void) { uint8_t n=45; while (n--) { NOP(); } }
+
+#endif // HAL_DELAY_H_
diff --git a/OpenSky/arch/cc251x/hal_dma.c b/OpenSky/arch/cc251x/hal_dma.c
new file mode 100644
index 0000000..05f6bd7
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_dma.c
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "main.h"
+#include "hal_dma.h"
+
+// dma config
+// dma0 can be given independently but 1-4 has
+// to be given in one consequent array...
+__xdata HAL_DMA_DESC hal_dma_config[5];
diff --git a/OpenSky/arch/cc251x/hal_dma.h b/OpenSky/arch/cc251x/hal_dma.h
new file mode 100644
index 0000000..596065c
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_dma.h
@@ -0,0 +1,152 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DMA_H_
+#define HAL_DMA_H_
+
+#include
+
+// HAL_DMA CONFIG
+// see https:// e2e.ti.com/support/wireless_connectivity/f/156/t/16922
+typedef struct {
+ uint8_t SRCADDRH;
+ uint8_t SRCADDRL;
+ uint8_t DESTADDRH;
+ uint8_t DESTADDRL;
+ uint8_t LENH : 5;
+ uint8_t VLEN : 3;
+ uint8_t LENL : 8;
+ uint8_t TRIG : 5;
+ uint8_t TMODE : 2;
+ uint8_t WORDSIZE : 1;
+ uint8_t PRIORITY : 2;
+ uint8_t M8 : 1;
+ uint8_t IRQMASK : 1;
+ uint8_t DESTINC : 2;
+ uint8_t SRCINC : 2;
+} HAL_DMA_DESC;
+
+extern __xdata HAL_DMA_DESC hal_dma_config[5];
+
+// Use LEN for transfer count
+#define DMA_VLEN_USE_LEN 0x00
+// Transfer the number of bytes specified by the first byte +1
+#define DMA_VLEN_FIRST_BYTE_P_1 0x01
+// Transfer the number of bytes indicated by the first byte (itself included)
+#define DMA_VLEN_FIRST_BYTE 0x02
+// Transfer the number of bytes specified by the first byte +2
+#define DMA_VLEN_FIRST_BYTE_P_2 0x03
+// Transfer the number of bytes specified by the first byte +3
+#define DMA_VLEN_FIRST_BYTE_P_3 0x04
+// The maximum length is always decided by the first byte
+#define DMA_LEN_MAX 0xFF
+// Transfer a byte at a time
+#define DMA_WORDSIZE_BYTE 0x00
+// Transfer a 16-bit word at a time
+#define DMA_WORDSIZE_WORD 0x01
+// Transfer a single byte/word after each DMA trigger
+#define DMA_TMODE_SINGLE 0x00
+// Transfer block of data (length len) after each DMA trigger
+#define DMA_TMODE_BLOCK 0x01
+// Transfer single byte/word (after len transfers, rearm DMA)
+#define DMA_TMODE_SINGLE_REPEATED 0x02
+// Transfer block of data (after len transfers, rearm DMA)
+#define DMA_TMODE_BLOCK_REPEATED 0x03
+
+#define DMA_TRIG_NONE 0 // No trigger, setting DMAREQ.DMAREQx bit starts transfer
+#define DMA_TRIG_PREV 1 // DMA channel is triggered by completion of previous channel
+#define DMA_TRIG_T1_CH0 2 // Timer 1, compare, channel 0
+#define DMA_TRIG_T1_CH1 3 // Timer 1, compare, channel 1
+#define DMA_TRIG_T1_CH2 4 // Timer 1, compare, channel 2
+#define DMA_TRIG_T2_COMP 5 // Timer 2, compare
+#define DMA_TRIG_T2_OVFL 6 // Timer 2, overflow
+#define DMA_TRIG_T3_CH0 7 // Timer 3, compare, channel 0
+#define DMA_TRIG_T3_CH1 8 // Timer 3, compare, channel 1
+#define DMA_TRIG_T4_CH0 9 // Timer 4, compare, channel 0
+#define DMA_TRIG_T4_CH1 10 // Timer 4, compare, channel 1
+#define DMA_TRIG_ST 11 // Sleep Timer compare
+#define DMA_TRIG_IOC_0 12 // Port 0 I/O pin input transition
+#define DMA_TRIG_IOC_1 13 // Port 1 I/O pin input transition
+#define DMA_TRIG_URX0 14 // USART0 RX complete
+#define DMA_TRIG_UTX0 15 // USART0 TX complete
+#define DMA_TRIG_URX1 16 // USART1 RX complete
+#define DMA_TRIG_UTX1 17 // USART1 TX complete
+#define DMA_TRIG_FLASH 18 // Flash data write complete
+#define DMA_TRIG_RADIO 19 // RF packet byte received/transmit
+#define DMA_TRIG_ADC_CHALL 20 // ADC end of a conversion in a sequence, sample ready
+#define DMA_TRIG_ADC_CH0 21 // ADC end of conversion channel 0 in sequence, sample ready
+#define DMA_TRIG_ADC_CH1 22 // ADC end of conversion channel 1 in sequence, sample ready
+#define DMA_TRIG_ADC_CH2 23 // ADC end of conversion channel 2 in sequence, sample ready
+#define DMA_TRIG_ADC_CH3 24 // ADC end of conversion channel 3 in sequence, sample ready
+#define DMA_TRIG_ADC_CH4 25 // ADC end of conversion channel 4 in sequence, sample ready
+#define DMA_TRIG_ADC_CH5 26 // ADC end of conversion channel 5 in sequence, sample ready
+#define DMA_TRIG_ADC_CH6 27 // ADC end of conversion channel 6 in sequence, sample ready
+#define DMA_TRIG_ADC_CH7 28 // ADC end of conversion channel 7 in sequence, sample ready
+#define DMA_TRIG_ENC_DW 29 // AES encryption processor requests download input data
+#define DMA_TRIG_ENC_UP 30 // AES encryption processor requests upload output data
+
+// Increment source pointer by 0 bytes/words after each transfer
+#define DMA_SRCINC_0 0x00
+// Increment source pointer by 1 bytes/words after each transfer
+#define DMA_SRCINC_1 0x01
+// Increment source pointer by 2 bytes/words after each transfer
+#define DMA_SRCINC_2 0x02
+// Decrement source pointer by 1 bytes/words after each transfer
+#define DMA_SRCINC_M1 0x03
+
+// Increment destination pointer by 0 bytes/words after each transfer
+#define DMA_DESTINC_0 0x00
+// Increment destination pointer by 1 bytes/words after each transfer
+#define DMA_DESTINC_1 0x01
+// Increment destination pointer by 2 bytes/words after each transfer
+#define DMA_DESTINC_2 0x02
+// Decrement destination pointer by 1 bytes/words after each transfer
+#define DMA_DESTINC_M1 0x03
+
+// Disable interrupt generation
+#define DMA_IRQMASK_DISABLE 0x00
+// Enable interrupt generation upon DMA channel done
+#define DMA_IRQMASK_ENABLE 0x01
+
+#define DMA_M8_USE_8_BITS 0x00 // Use all 8 bits for transfer count
+#define DMA_M8_USE_7_BITS 0x01 // Use 7 LSB for transfer count
+
+// Low, CPU has priority
+#define DMA_PRI_LOW 0x00
+// Guaranteed, DMA at least every second try
+#define DMA_PRI_GUARANTEED 0x01
+// High, DMA has priority
+#define DMA_PRI_HIGH 0x02
+// Highest, DMA has priority. Reserved for DMA port access.
+#define DMA_PRI_ABSOLUTE 0x03
+
+#define DMA_ARM_ABORT 0x80
+#define DMA_ARM_CH0 (1<<0)
+#define DMA_ARM_CH1 (1<<1)
+#define DMA_ARM_CH2 (1<<2)
+#define DMA_ARM_CH3 (1<<3)
+#define DMA_ARM_CH4 (1<<4)
+
+#define DMAIRQ_DMAIF0 (1<<0)
+#define DMAIRQ_DMAIF1 (1<<1)
+#define DMAIRQ_DMAIF2 (1<<2)
+#define DMAIRQ_DMAIF3 (1<<3)
+#define DMAIRQ_DMAIF4 (1<<4)
+
+#endif // HAL_DMA_H_
diff --git a/OpenSky/arch/cc251x/hal_io.c b/OpenSky/arch/cc251x/hal_io.c
new file mode 100644
index 0000000..fde6c97
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_io.c
@@ -0,0 +1,56 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_io.h"
+#include "portmacros.h"
+#include "config.h"
+#include "hal_cc25xx.h"
+
+void hal_io_init(void) {
+ // set bind pin as input
+ PORT2DIR(BIND_PORT) &= ~(1 << BIND_PIN);
+ // set pullup/down
+ PORT2INP(BIND_PORT) &= ~(1 << BIND_PIN);
+
+#ifdef BIND2_PORT
+ // this board allows two bind buttons, both will work
+ // set bind2 pin as input
+ PORT2DIR(BIND2_PORT) &= ~(1 << BIND2_PIN);
+ // set pullup/down
+ PORT2INP(BIND2_PORT) &= ~(1 << BIND2_PIN);
+#endif // BIND2_PORT
+}
+
+uint8_t hal_io_bind_request(void) {
+ // test bind button
+ if (!(BIND_PORT & (1 << BIND_PIN))) {
+ // LOW -> button pressed
+ return 1;
+ }
+
+ #ifdef BIND2_PORT
+ if (!(BIND2_PORT & (1 << BIND2_PIN))) {
+ // LOW -> button2 pressed
+ return 1;
+ }
+ #endif // BIND2_PORT
+
+ // no button pressed...
+ return 0;
+}
diff --git a/OpenSky/arch/cc251x/hal_io.h b/OpenSky/arch/cc251x/hal_io.h
new file mode 100644
index 0000000..187456d
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_io.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_IO_H_
+#define HAL_IO_H_
+#include "portmacros.h"
+#include "config.h"
+#include
+
+void hal_io_init(void);
+uint8_t hal_io_bind_request(void);
+
+#endif // HAL_IO_H_
diff --git a/OpenSky/arch/cc251x/hal_led.c b/OpenSky/arch/cc251x/hal_led.c
new file mode 100644
index 0000000..c405776
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_led.c
@@ -0,0 +1,22 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_led.h"
+
+// nothing to do
diff --git a/OpenSky/arch/cc251x/hal_led.h b/OpenSky/arch/cc251x/hal_led.h
new file mode 100644
index 0000000..a3b5f8a
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_led.h
@@ -0,0 +1,44 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_LED_H_
+#define HAL_LED_H_
+
+#include "portmacros.h"
+#include "config.h"
+#include "hal_cc25xx.h"
+
+// use helper macros to do expansion to *DIR etc
+// LEDS
+#define LED_GREEN_DIR PORT2DIR(LED_GREEN_PORT)
+#define LED_RED_DIR PORT2DIR(LED_RED_PORT)
+#define LED_RED_BIT PORT2BIT(LED_RED_PORT, LED_RED_PIN)
+#define LED_GREEN_BIT PORT2BIT(LED_GREEN_PORT, LED_GREEN_PIN)
+
+#define hal_led_green_init() { LED_GREEN_DIR |= (1 << LED_GREEN_PIN); led_green_off(); }
+#define hal_led_green_on() { LED_GREEN_BIT = 1; }
+#define hal_led_green_off() { LED_GREEN_BIT = 0; }
+#define hal_led_green_toggle() { LED_GREEN_BIT = !LED_GREEN_BIT; }
+
+#define hal_led_red_init() { LED_RED_DIR |= (1 << LED_RED_PIN); led_red_off(); }
+#define hal_led_red_on() { LED_RED_BIT = 1; }
+#define hal_led_red_off() { LED_RED_BIT = 0; }
+#define hal_led_red_toggle() { LED_RED_BIT = !LED_RED_BIT; }
+
+#endif // HAL_LED_H_
diff --git a/OpenSky/arch/cc251x/hal_ppm.c b/OpenSky/arch/cc251x/hal_ppm.c
new file mode 100644
index 0000000..3354a39
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_ppm.c
@@ -0,0 +1,116 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_ppm.h"
+#include "ppm.h"
+
+#ifndef SBUS_ENABLED
+
+void hal_ppm_init(void) {
+ // no int on overflow:
+ OVFIM = 0;
+
+ // set channels to compare interupt:
+ // CH0: off
+ T1CCTL0 = 0;
+ // CH1: off
+ T1CCTL1 = 0;
+ // CH2: toggle pin on cmp match, will generate sync pulses
+ #if PPM_INVERTED
+ // inverted, set on match, clear on zero
+ T1CCTL2 = T1CCTLx_MODE_COMPARE | T1CCTLx_CMP_SETCLR0;
+ #else
+ // non-inverted, clear on match, set on zero
+ T1CCTL2 = T1CCTLx_MODE_COMPARE | T1CCTLx_CMP_CLRSET0;
+ #endif // PPM_INVERTED
+
+ // configure peripheral alternative1 for timer 1:
+ // use alt config 1 -> clr flag -> P0_4 = output
+ PERCFG &= ~(PERCFG_T1CFG);
+
+ // USART1 use ALT2 in order to free up P0_4 for peripheral func
+ PERCFG |= PERCFG_U1CFG;
+
+ // select P0_4 for peripheral function
+ // NOTE: make sure to set usart1 to alt2 config!
+ P0SEL |= (1 << PPM_OUT_PIN);
+
+ // select P0_4 as output
+ P0DIR |= (1 << PPM_OUT_PIN);
+
+ // prescaler = 128
+ // tickspeed = 26MHz / 8 = 3,25MHz (TICKSPD is set in timeout.c!)
+ // 1us = 3.25 ticks -> 2ms = 6500 ticks, 4ms = 13000
+ T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_1;
+
+
+ // ch2 cmp: sync pulse length
+ SET_WORD_LO_FIRST(T1CC2H, T1CC2L, PPM_SYNC_PULS_LEN_TICKS);
+
+ // overflow:
+ SET_WORD_LO_FIRST(T1CC0H, T1CC0L, HAL_PPM_US_TO_TICKCOUNT(1000));
+
+ ppm_output_index = 0;
+
+ // clear pending interrupt flags (IRCON is reset by hw)
+ T1CTL &= ~(T1CTL_CH0_IF | T1CTL_CH1_IF | T1CTL_CH2_IF | T1CTL_OVFIF);
+
+ // overflow causes an int -> reload next channel data
+ OVFIM = 1;
+
+ // enable T1 interrups
+ T1IE = 1;
+}
+
+
+void hal_ppm_failsafe_exit() {
+ // configure p0_4 as peripheral:
+ P0SEL |= (1<<4);
+
+ // reset counter:
+ SET_WORD_LO_FIRST(T1CNTH, T1CNTL, 0);
+
+ // re enable timer interrupts:
+ OVFIM = 1;
+
+ // disable T1 interrups
+ T1IE = 1;
+}
+
+void hal_ppm_failsafe_enter(void) {
+ // disable interrupts
+ OVFIM = 0;
+
+ // disable T1 interrups
+ T1IE = 0;
+
+ // configure p0_4 as normal i/o:
+ P0SEL &= ~(1<<4);
+
+ // set pins to failsafe level:
+ #if PPM_INVERTED
+ // clear on zero -> default is high
+ P0 |= (1<<4);
+ #else
+ // set on zero -> default is low
+ P0 &= ~(1<<4);
+ #endif // PPM_INVERTED
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/cc251x/hal_ppm.h b/OpenSky/arch/cc251x/hal_ppm.h
new file mode 100644
index 0000000..cc13e62
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_ppm.h
@@ -0,0 +1,68 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_PPM_H_
+#define HAL_PPM_H_
+
+#include "config.h"
+#include "hal_cc25xx.h"
+#include
+
+#ifdef SBUS_ENABLED
+#define hal_ppm_init() {}
+#else
+void hal_ppm_init(void);
+
+void hal_ppm_failsafe_exit(void);
+void hal_ppm_failsafe_enter(void);
+
+void hal_ppm_timer1_interrupt(void) __interrupt T1_VECTOR;
+
+/*
+static void hal_ppm_init_rcc(void);
+static void hal_ppm_init_gpio(void);
+static void hal_ppm_init_timer(void);
+static void hal_ppm_init_nvic(void);
+static void hal_ppm_init_ocx(uint8_t ch, TIM_TypeDef *TIMx, TIM_OCInitTypeDef *tim_oc_init);
+*/
+
+
+
+// from frsky to ticks coresponding to 1000...2000 us
+// frsky seems to send us*1.5 (~1480...3020) -> divide by 1.5 (=*2/3) to get us
+// us -> ticks = ((_us*13)/4) -> (((_frsky*2/3)*13)/4) = ((_frsky*13)/6)
+#define HAL_PPM_FRSKY_TO_TICKCOUNT(_frsky) (((_frsky << 3) + (_frsky << 2)+(_frsky))/6)
+
+// from us to ticks:
+// ((_us*13)/4) = ((_us * (8+4+1))/4) = (((_us<<3)+(_us<<2)+(_us))>>2)
+#define HAL_PPM_US_TO_TICKCOUNT(_us) (((_us << 3) + (_us << 2)+(_us)) >> 2)
+
+
+#define PPM_TIMER_ISR(void) hal_ppm_timer1_interrupt(void) __interrupt T1_VECTOR
+
+#define HAL_PPM_UPDATE_CCVALUE(val) SET_WORD_LO_FIRST(T1CC0H, T1CC0L, val)
+#define HAL_PPM_ISR_DISABLE() { cli(); }
+#define HAL_PPM_ISR_ENABLE() { sei(); }
+#define HAL_PPM_ISR_FLAG_SET() (1)
+#define HAL_PPM_ISR_CLEAR_FLAG() { \
+ T1CTL &= ~(T1CTL_CH0_IF | T1CTL_CH1_IF | T1CTL_CH2_IF | T1CTL_OVFIF);}
+
+#endif // SBUS_ENABLED
+
+#endif // HAL_PPM_H_
diff --git a/OpenSky/arch/cc251x/hal_sbus.c b/OpenSky/arch/cc251x/hal_sbus.c
new file mode 100644
index 0000000..f290c23
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_sbus.c
@@ -0,0 +1,22 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "sbus.h"
+
+
diff --git a/OpenSky/arch/cc251x/hal_sbus.h b/OpenSky/arch/cc251x/hal_sbus.h
new file mode 100644
index 0000000..636a2c3
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_sbus.h
@@ -0,0 +1,36 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SBUS_H_
+#define HAL_SBUS_H_
+
+#include
+#include "hal_defines.h"
+#include "hal_uart.h"
+
+// this helper routine will invert the data
+// stored in buffer in case the sbus is set
+// to inverted
+#ifdef SBUS_INVERTED
+ #define HAL_SBUS_PREPARE_DATA(a) (0xFF ^ (a))
+#else
+ #define HAL_SBUS_PREPARE_DATA(a) (a)
+#endif // SBUS_INVERTED
+
+#endif // HAL_SBUS_H_
diff --git a/OpenSky/arch/cc251x/hal_soft_serial.c b/OpenSky/arch/cc251x/hal_soft_serial.c
new file mode 100644
index 0000000..161257d
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_soft_serial.c
@@ -0,0 +1,151 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_soft_serial.h"
+#include "soft_serial.h"
+#include "debug.h"
+#include "delay.h"
+#include "led.h"
+#include "wdt.h"
+#include "config.h"
+#include "portmacros.h"
+#include "hal_cc25xx.h"
+
+#ifndef HUB_TELEMETRY_ON_SBUS_UART
+
+void hal_soft_serial_init(void) {
+ debug("hal_soft_serial: init\n"); debug_flush();
+ hal_soft_serial_init_gpio();
+ hal_soft_serial_init_interrupts();
+}
+
+void hal_soft_serial_init_gpio(void) {
+ // set gpio as input
+ PORT2DIR(HUB_TELEMETRY_PORT) &= ~(1 << HUB_TELEMETRY_PIN);
+}
+
+void hal_soft_serial_init_interrupts(void) {
+ OVFIM = 0;
+
+ // disable compare modes
+ T4CCTL0 = 0;
+ T4CCTL1 = 0;
+
+ // tickspeed = 26MHz / 8 = 3,25MHz (TICKSPD is set in hal_timeout.c!)
+ // 1us = 3.25 ticks -> DIV2 -> 1us = 1.625 ticks
+ T4CTL = T4CTL_DIV_2 | // /2
+ T4CTL_START | // start
+ T4CTL_OVFIM | // OVInt enabled
+ T4CTL_CLR | // clear
+ T4CTL_MODE_MODULO; // 01 = count to CC and the overflow
+
+ // ch0 cmp: bit length
+ T4CC0 = HAL_SOFTSERIAL_BIT_DURATION_TICKS;
+
+ // clear pending interrupt flags (IRCON is reset by hw)
+ T4OVFIF = 0;
+
+ // overflow causes an int -> reload next channel data
+ OVFIM = 1;
+
+ // enable T4 interrups
+ IEN1 |= IEN1_T4IE;
+
+ // clear pending port ints
+ P0IFG = 0;
+ P0IF = 0;
+
+ // enable interrupts on P0 4...7
+ PICTL |= PICTL_P0IENH;
+ P0SEL &= ~(1<<6);
+
+ // set edge:
+#ifdef HUB_TELEMETRY_INVERTED
+ // rising edge triggers isr
+ PICTL &= ~PICTL_P0ICON;
+#else
+ // falling edge triggers isr
+ PICTL |= PICTL_P0ICON;
+#endif // HUB_TELEMETRY_INVERTED
+
+ // T4 highest int prio (group4)
+ IP0 |= (1 << 4);
+ IP1 |= (1 << 4);
+ // P0 highest int prio (group5)
+ IP0 |= (1 << 5);
+ IP1 |= (1 << 5);
+
+ // enable interrupts from P0
+ P0IF = 0;
+ P0IFG = 0;
+ IEN1 |= IEN1_P0IE;
+}
+
+
+void hal_soft_serial_update_interrupt(void) __interrupt T4_VECTOR {
+ if (T4OVFIF) {
+ // DEBUG_PIN_TOGGLE();
+
+ // re-arm for the next bit
+ HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(HAL_SOFTSERIAL_BIT_DURATION_TICKS-1);
+
+ if (soft_serial_process_databit()) {
+ // finished transmission, disable UP and enable IC isr
+ IEN1 |= IEN1_P0IE;
+ IEN1 &= ~IEN1_T4IE;
+ }
+
+ // clear pending interrupt flags (IRCON is reset by hw)
+ T4OVFIF = 0;
+ P0IFG = 0;
+ P0IF = 0;
+ }
+}
+
+void hal_soft_serial_startbit_interrupt(void) __interrupt P0INT_VECTOR {
+ uint8_t isr_cause = P0IFG;
+
+ // clear int flags WARNING: order seems to be important! CLR first IFG then IF!
+ P0IFG = 0;
+ // clear P0 int flags (important: several P0 pins can cause the isr, clean all of them!)
+ P0IF = 0;
+
+ if (isr_cause & (1 << HUB_TELEMETRY_PIN)) {
+ // DEBUG_PIN_TOGGLE();
+ // reset t3 counter:
+ T4CTL |= T4CTL_CLR;
+ // disable IC interrupt (only compare match interrupts will follow)
+ IEN1 &= ~IEN1_P0IE;
+ // enable overflow isr
+ IEN1 |= IEN1_T4IE;
+
+ // this is the startbit -> re synchronize the timer to this
+ // by setting the next cc interrupt to 1/2 bit length:
+ HAL_SOFT_SERIAL_UPDATE_TOP_VALUE((HAL_SOFTSERIAL_BIT_DURATION_TICKS / 2)-1);
+
+ // clear pending int flags
+ P0IF = 0;
+ T4OVFIF = 0;
+
+ // process
+ soft_serial_process_startbit();
+ }
+}
+
+#endif // HUB_TELEMETRY_ON_SBUS_UART
diff --git a/OpenSky/arch/cc251x/hal_soft_serial.h b/OpenSky/arch/cc251x/hal_soft_serial.h
new file mode 100644
index 0000000..ce45d2a
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_soft_serial.h
@@ -0,0 +1,49 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SOFT_SERIAL_H_
+#define HAL_SOFT_SERIAL_H_
+
+#include "hal_cc25xx.h"
+#include "cc2510fx.h"
+#include "config.h"
+
+#ifndef HUB_TELEMETRY_ON_SBUS_UART
+
+void hal_soft_serial_init(void);
+void hal_soft_serial_init_gpio(void);
+void hal_soft_serial_init_interrupts(void);
+
+// at 9600 baud a bit duration is 1/9600s = 104.166667us
+// the counter counts in 1/1.625th of us -> 104.1667us * 1.625
+// = 169,27... -> 169 -> 0.16% error (thats ok..)
+#define HAL_SOFTSERIAL_BIT_DURATION_TICKS (169)
+
+#define HUB_TELEMETRY_PIN_HI() (HUB_TELEMETRY_PORT & (1 << HUB_TELEMETRY_PIN))
+#define HUB_TELEMETRY_PIN_LO() (!HUB_TELEMETRY_PIN_HI())
+
+#define HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(x) { T4CC0 = x; }
+
+extern void hal_soft_serial_update_interrupt(void) __interrupt T4_VECTOR;
+extern void hal_soft_serial_startbit_interrupt(void) __interrupt P0INT_VECTOR;
+
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+
+#endif // HAL_SOFT_SERIAL_H_
+
diff --git a/OpenSky/arch/cc251x/hal_spi.c b/OpenSky/arch/cc251x/hal_spi.c
new file mode 100644
index 0000000..ae2293f
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_spi.c
@@ -0,0 +1,24 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_spi.h"
+
+void hal_spi_init(void) {
+}
+
diff --git a/OpenSky/arch/cc251x/hal_spi.h b/OpenSky/arch/cc251x/hal_spi.h
new file mode 100644
index 0000000..67e412e
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_spi.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SPI_H_
+#define HAL_SPI_H_
+
+void hal_spi_init(void);
+
+#endif // HAL_SPI_H_
+
diff --git a/OpenSky/arch/cc251x/hal_storage.c b/OpenSky/arch/cc251x/hal_storage.c
new file mode 100644
index 0000000..b7eb02c
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_storage.c
@@ -0,0 +1,205 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_storage.h"
+#include
+#include "debug.h"
+#include "main.h"
+#include "delay.h"
+#include "wdt.h"
+
+
+__xdata HAL_DMA_DESC flash_dma_config;
+// no ini value -> sdcc does not init this!
+__code __at(STORAGE_LOCATION) uint8_t storage_on_flash[STORAGE_PAGE_SIZE];
+
+void hal_storage_init(void) {
+ debug("hal_storage: init\n"); debug_flush();
+}
+
+void hal_storage_write(uint8_t *buffer, uint16_t len) {
+ hal_storage_flash_write((uint16_t)storage_on_flash, buffer, len);
+}
+
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len) {
+ uint16_t i;
+
+ debug("hal_storage: loading from flash: "); debug_flush();
+
+ // copy from persistant flash to ram:
+ for (i = 0; i < len; i++) {
+ storage_ptr[i] = storage_on_flash[i];
+ debug_put_hex8(storage_on_flash[i]); debug_putc(' '); debug_flush();
+ wdt_reset();
+ }
+}
+
+static void hal_storage_flash_write(uint16_t address, uint8_t *data, uint16_t len) {
+ uint16_t i = 0;
+ uint8_t *flash_ptr = 0;
+
+ debug("hal_storage: will write page at 0x"); debug_flush();
+ debug_put_hex8(address >> 8);
+ debug_put_hex8(address & 0xff);
+ debug_put_newline();
+
+ // this is VERY important:
+ // make sure to write an even number of bytes!
+ // simply write one extra byte
+ if (len & 0x0001) {
+ debug("flash: corrected len to even\n");
+ len++;
+ }
+
+ // disable interrupts
+ cli();
+
+ // cancel _ALL_ ongoing DMA transfers:
+ DMAARM = DMA_ARM_ABORT | 0x1F;
+
+ // high prio
+ flash_dma_config.PRIORITY = DMA_PRI_HIGH;
+ // irrelevant since we use LEN for transfer count
+ flash_dma_config.M8 = DMA_M8_USE_8_BITS;
+ // disable ints from this ch
+ flash_dma_config.IRQMASK = DMA_IRQMASK_DISABLE;
+ // use dma flash data write complete trigger
+ flash_dma_config.TRIG = DMA_TRIG_FLASH;
+ // single mode, see datasheet
+ flash_dma_config.TMODE = DMA_TMODE_SINGLE;
+ // one byte
+ flash_dma_config.WORDSIZE = DMA_WORDSIZE_BYTE;
+
+ // set src: address of data to be written
+ SET_WORD(flash_dma_config.SRCADDRH, flash_dma_config.SRCADDRL, data);
+ // destination is flash controller data reg
+ SET_WORD(flash_dma_config.DESTADDRH, flash_dma_config.DESTADDRL, &X_FWDATA);
+ // use LEN
+ flash_dma_config.VLEN = DMA_VLEN_USE_LEN;
+ // set length
+ SET_WORD(flash_dma_config.LENH, flash_dma_config.LENL, len);
+ // set srcinc to 1 byte
+ flash_dma_config.SRCINC = DMA_SRCINC_1;
+ // fixed, always write to FWDATA
+ flash_dma_config.DESTINC = DMA_DESTINC_0;
+
+ // Save pointer to the DMA configuration struct into DMA-channel 0
+ // configuration registers
+ SET_WORD(DMA0CFGH, DMA0CFGL, flash_dma_config);
+
+ // waiting for the flash controller to be ready
+ while (FCTL & FCTL_BUSY) {}
+
+ // configure flash controller for 26mhz clock
+ FWT = 0x2A; // (21 * 26) / (16);
+
+ // set up address:
+ SET_WORD(FADDRH, FADDRL, ((uint16_t)address)>>1);
+
+ // re enable ints
+ sei();
+
+ debug("hal_storage: erasing page\n"); debug_flush();
+
+ // disable interrupts
+ cli();
+
+ // clear any pending flags
+ DMAIRQ = 0;
+
+ // erase that page
+ // has to be 2byte aligned. use a hack to place it at a given adress:
+ hal_storage_flash_erase_page();
+
+ // Wait for the erase operation to complete
+ while (FCTL & FCTL_BUSY) {}
+
+ // FCTL = 0;
+
+ // re enable ints
+ sei();
+
+ debug("hal_storage: erase done\n"); debug_flush();
+
+ debug("hal_storage: will write ["); debug_flush();
+ i = 0;
+ while (i < len) {
+ debug_put_hex8(((uint8_t *)data)[i++]);
+ debug_put_hex8(((uint8_t *)data)[i++]);
+ debug_putc(' ');
+ debug_flush();
+ }
+ debug("]\n");
+
+ debug("hal_storage: will write flash now\n"); debug_flush();
+
+ // disable interrupts
+ cli();
+
+ // arm the DMA channel, so that a DMA trigger will initiate DMA writing
+ DMAARM = DMA_ARM_CH0;
+ NOP();
+
+ // enable flash write. this generates a DMA trigger.
+ // must be aligned on a 2-byte boundary and is therefor implemented in assembly!
+ hal_storage_flash_enable_write();
+
+
+ // wait for dma finish
+ while (!(DMAIRQ & DMAIRQ_DMAIF0)) {
+ wdt_reset();
+ }
+
+ // wait until flash controller not busy
+ while (FCTL & (FCTL_BUSY | FCTL_SWBUSY)) {}
+
+ sei();
+
+ // by now, the transfer is completed, so the transfer count is reached.
+ // the DMA channel 0 interrupt flag is then set, so we clear it here.
+ DMAIRQ &= ~DMAIRQ_DMAIF0;
+
+
+ debug("hal_storage: read back [");
+ // copy from persistant flash to ram:
+ flash_ptr = address;
+ for (i = 0; i < len; i++) {
+ debug_put_hex8(*flash_ptr++); debug_putc(' '); debug_flush();
+ wdt_reset();
+ }
+ debug("]\n");
+
+ debug("hal_storage: write done");
+}
+
+void hal_storage_flash_enable_write(void) {
+ __asm
+ .even // IMPORTANT: PLACE THIS ON A 2BYTE BOUNDARY!
+ ORL _FCTL, #0x02; // FCTL |= FCTL_WRITE
+ NOP;
+ __endasm;
+}
+
+void hal_storage_flash_erase_page(void) {
+ __asm
+ .even // IMPORTANT: PLACE THIS ON A 2BYTE BOUNDARY!
+ ORL _FCTL, #0x01; // FCTL |= FCTL_ERASE
+ NOP; // required sequence!
+ __endasm;
+}
diff --git a/OpenSky/arch/cc251x/hal_storage.h b/OpenSky/arch/cc251x/hal_storage.h
new file mode 100644
index 0000000..984f04b
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_storage.h
@@ -0,0 +1,45 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_STORAGE_H_
+#define HAL_STORAGE_H_
+
+#include
+#include "hal_cc25xx.h"
+#include "hal_dma.h"
+
+// place data on end of flash
+// FIXME: this is for a cc2510f16 with flash size 0x4000, needs to be adjusted for bigger mcus
+#define STORAGE_PAGE_SIZE 1024
+#define STORAGE_LOCATION (0x4000-STORAGE_PAGE_SIZE)
+
+// place persistant storage:
+extern __code __at(STORAGE_LOCATION) uint8_t storage_on_flash[STORAGE_PAGE_SIZE];
+extern __xdata HAL_DMA_DESC flash_dma_config;
+
+
+void hal_storage_init(void);
+void hal_storage_write(uint8_t *buffer, uint16_t len);
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len);
+
+static void hal_storage_flash_write(uint16_t address, uint8_t *data, uint16_t len);
+void hal_storage_flash_enable_write(void);
+void hal_storage_flash_erase_page(void);
+
+#endif // HAL_STORAGE_H_
diff --git a/OpenSky/arch/cc251x/hal_timeout.c b/OpenSky/arch/cc251x/hal_timeout.c
new file mode 100644
index 0000000..d706910
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_timeout.c
@@ -0,0 +1,135 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_timeout.h"
+#include "delay.h"
+#include "debug.h"
+#include "timeout.h"
+#include "hal_cc25xx.h"
+
+// do not place this in xdata (faster this way)
+volatile uint16_t hal_timeout_countdown;
+volatile uint16_t hal_timeout2_countdown;
+
+void hal_timeout_init(void) {
+ debug("hal_timeout: init\n"); debug_flush();
+
+ // timer clock
+ CLKCON = (CLKCON & ~CLKCON_TICKSPD_111) | CLKCON_TICKSPD_011;
+
+ // prepare timer3 for 1/25th ms steps:
+ // TICKSPD 011 -> /8 = 3250 kHz timer clock input
+ T3CTL = T3CTL_DIV_2 | // /2
+ T3CTL_START | // start
+ T3CTL_OVFIM | // OVInt enabled
+ T3CTL_CLR | // clear
+ T3CTL_MODE_MODULO; // 01 = count to CC and the overflow
+
+ // 3250/2/65 = 25khz
+ T3CC0 = 65-1;
+
+ // enable int
+ IEN1 |= (IEN1_T3IE);
+
+ timeout_set(0);
+
+ /*LED_RED_OFF();
+ while (1) {
+ timeout_set(990);
+ LED_GREEN_OFF();
+ while (!timeout_timed_out()) {}
+ timeout_set(10);
+ LED_GREEN_ON();
+ while (!timeout_timed_out()) {}
+ }*/
+
+ /* // TEST timings
+ P0DIR |= (1<<7);
+ while (1) {
+ timeout_set(1);
+ while (!timeout_timed_out()) {}
+ P0 |= (1<<7);
+ LED_RED_ON();
+ delay_ms(100);
+ P0 &= ~(1<<7);
+ LED_RED_OFF();
+ }*/
+}
+
+// prepare a new timeout
+void hal_timeout_set(uint16_t timeout_ms) {
+ // disable T3ints:
+ IEN1 &= ~(IEN1_T3IE);
+
+ // clear counter
+// T3CTL |= (1<<2);
+
+ // clear pending ints
+// T3IF = 0;
+
+ // prepare timeout val:
+ hal_timeout_countdown = (timeout_ms * 25);
+
+ // clear pending ints
+// T3IF = 0;
+
+ // re enable interrupts
+ IEN1 |= IEN1_T3IE;
+}
+
+uint8_t hal_timeout_timed_out(void) {
+ if (hal_timeout_countdown == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+// prepare a new timeout
+void hal_timeout2_set_100us(uint16_t timeout_100us) {
+ hal_timeout2_countdown = (timeout_100us * 25) / 10;
+}
+
+// prepare a new timeout
+void hal_timeout2_set(uint16_t timeout_ms) {
+ hal_timeout2_countdown = (timeout_ms * 25);
+}
+
+
+uint8_t hal_timeout2_timed_out(void) {
+ if (hal_timeout2_countdown == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+void hal_timeout_interrupt(void) __interrupt T3_VECTOR {
+ // clear flag
+ T3IF = 0;
+
+ if (hal_timeout_countdown != 0) {
+ hal_timeout_countdown--;
+ }
+
+ if (hal_timeout2_countdown != 0) {
+ hal_timeout2_countdown--;
+ }
+}
diff --git a/OpenSky/arch/cc251x/hal_timeout.h b/OpenSky/arch/cc251x/hal_timeout.h
new file mode 100644
index 0000000..61c8a30
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_timeout.h
@@ -0,0 +1,38 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_TIMEOUT_H_
+#define HAL_TIMEOUT_H_
+
+#include
+#include "cc2510fx.h"
+
+extern volatile uint16_t hal_timeout_countdown;
+
+void hal_timeout_init(void);
+void hal_timeout_set(uint16_t timeout_ms);
+uint8_t hal_timeout_timed_out(void);
+
+void hal_timeout2_set(uint16_t ms);
+void hal_timeout2_set_100us(uint16_t hus);
+uint8_t hal_timeout2_timed_out(void);
+
+void hal_timeout_interrupt(void) __interrupt T3_VECTOR;
+
+#endif // HAL_TIMEOUT_H_
diff --git a/OpenSky/arch/cc251x/hal_uart.c b/OpenSky/arch/cc251x/hal_uart.c
new file mode 100644
index 0000000..4a63811
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_uart.c
@@ -0,0 +1,258 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "cc2510fx.h"
+#include "hal_cc25xx.h"
+#include "hal_uart.h"
+#include "hal_defines.h"
+#include "hal_delay.h"
+#include "config.h"
+#include "hal_dma.h"
+#include "uart.h"
+#include "debug.h"
+#include "wdt.h"
+#include "delay.h"
+#include "led.h"
+
+void hal_uart_init(void) {
+ EXTERNAL_MEMORY union hal_uart_config_t sbus_uart_config;
+
+#if SBUS_UART == USART0_P1
+ // -> USART0_P1
+ // use ALT2 -> Set flag -> P1_5 = TX / P1_4 = RX
+ PERCFG |= (PERCFG_U0CFG);
+
+ // configure pins as peripheral:
+ P1SEL |= (1<<5) | (1<<4);
+
+ // make sure all P0 pins switch to normal GPIO
+ P0SEL &= ~(0x3C);
+
+ // make tx pin output:
+ P1DIR |= (1<<5);
+#elif SBUS_UART == USART1_P0
+ // USART1 use ALT1 -> Clear flag -> Port P0_4 = TX
+ PERCFG &= ~(PERCFG_U1CFG);
+
+ // USART1 has priority when USART0 is also enabled
+ P2DIR = (P2DIR & 0x3F) | 0b01000000;
+
+ // configure pin P0_4 (TX) and P0_5 (RX) as special function:
+ P0SEL |= (1<<4) | (1<<5);
+
+ // make sure all P1 pins switch to normal GPIO
+// P1SEL &= ~(0xF0);
+
+ // make tx pin output:
+ P0DIR |= (1<<4);
+#elif SBUS_UART == USART1_P1
+ // USART1 use ALT2 -> SET flag -> Port P1_6 = TX
+ PERCFG |= (PERCFG_U1CFG);
+
+ // USART1 has priority when USART0 is also enabled
+ P2DIR = (P2DIR & 0x3F) | 0b01000000;
+
+ // configure pin P1_6 (TX) and P1_7(RX) as special function:
+ P1SEL |= (1<<6) | (1<<7);
+
+ // make tx pin output:
+ P1DIR |= (1<<6);
+#else
+ #error "UNSUPPORTED UART"
+#endif // SBUS_UART == ...
+
+ // set baudrate
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ U0BAUD = CC2510_BAUD_M_100000;
+ U0GCR = (U0GCR & ~0x1F) | (CC2510_BAUD_E_100000);
+#else
+ U1BAUD = CC2510_BAUD_M_100000;
+ U1GCR = (U1GCR & ~0x1F) | (CC2510_BAUD_E_100000);
+#endif // SBUS_UART == ...
+
+ // set up config for USART -> 8E2
+ #ifdef SBUS_INVERTED
+ // this is a really nice feature of the cc2510:
+ // we can invert the idle level of the usart
+ // by setting STOP to zero. by inverting
+ // the parity, the startbit, and the data
+ // by using the SBUS_PREPARE_DATA() macro
+ // we can effectively invert the usart in software :)
+ sbus_uart_config.bit.START = 1; // startbit level = low
+ sbus_uart_config.bit.STOP = 0; // stopbit level = high
+ sbus_uart_config.bit.D9 = 1; // UNEven parity
+ #else
+ // standard usart, non-inverted mode
+ // NOTE: most sbus implementations use inverted mode
+ sbus_uart_config.bit.START = 0; // startbit level = low
+ sbus_uart_config.bit.STOP = 1; // stopbit level = high
+ sbus_uart_config.bit.D9 = 0; // Even parity
+ #endif // SBUS_INVERTED
+
+ sbus_uart_config.bit.SPB = 1; // 1 = 2 stopbits
+ sbus_uart_config.bit.PARITY = 1; // 1 = parity enabled, D9=0 -> even parity
+ sbus_uart_config.bit.BIT9 = 1; // 8bit
+ sbus_uart_config.bit.FLOW = 0; // no hw flow control
+ sbus_uart_config.bit.ORDER = 0; // lsb first
+
+ // activate uart config
+ hal_uart_set_mode(&sbus_uart_config);
+
+ // use dma channel 3 for transmission:
+ hal_dma_config[3].PRIORITY = DMA_PRI_LOW;
+ hal_dma_config[3].M8 = DMA_M8_USE_7_BITS;
+ hal_dma_config[3].IRQMASK = DMA_IRQMASK_DISABLE;
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ hal_dma_config[3].TRIG = DMA_TRIG_UTX0;
+#else
+ hal_dma_config[3].TRIG = DMA_TRIG_UTX1;
+#endif // SBUS_UART == ...
+ hal_dma_config[3].TMODE = DMA_TMODE_SINGLE;
+ hal_dma_config[3].WORDSIZE = DMA_WORDSIZE_BYTE;
+
+ // source address will be set during tx start
+ SET_WORD(hal_dma_config[3].SRCADDRH, hal_dma_config[3].SRCADDRL, 0);
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ SET_WORD(hal_dma_config[3].DESTADDRH, hal_dma_config[3].DESTADDRL, &X_U0DBUF);
+#else
+ SET_WORD(hal_dma_config[3].DESTADDRH, hal_dma_config[3].DESTADDRL, &X_U1DBUF);
+#endif // SBUS_UART == ...
+
+ hal_dma_config[3].VLEN = DMA_VLEN_USE_LEN;
+
+ // len will be set during tx start
+ SET_WORD(hal_dma_config[3].LENH, hal_dma_config[3].LENL, 0);
+
+ // configure src and dest increments
+ hal_dma_config[3].SRCINC = DMA_SRCINC_1;
+ hal_dma_config[3].DESTINC = DMA_DESTINC_0;
+
+ // set pointer to the DMA configuration struct into DMA-channel 1-4
+ // configuration, should have happened in adc.c already...
+ SET_WORD(DMA1CFGH, DMA1CFGL, &hal_dma_config[1]);
+
+ // arm the relevant DMA channel for UART TX, and apply 45 NOP's
+ // to allow the DMA configuration to load
+ // -> do a sleep instead of those nops...
+ DMAARM |= DMA_ARM_CH3;
+ hal_delay_45nop();
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+ // activate serial rx interrupt
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ URX0IF = 0;
+
+ // enable receiption
+ U0CSR |= UxCSR_RX_ENABLE;
+
+ // enable RX interrupt
+ URX0IE = 1;
+#else
+ URX1IF = 0;
+
+ // enable receiption
+ U1CSR |= UxCSR_RX_ENABLE;
+
+ // enable RX interrupt
+ URX1IE = 1;
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+
+ // enable global ints
+ EA = 1;
+#endif // SBUS_UART == ...
+}
+
+static void hal_uart_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg) {
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ // enable uart mode
+ U0CSR |= 0x80;
+
+ // store config to U1UCR register
+ U0UCR = cfg->byte & (0x7F);
+
+ // store config to U1GCR: (msb/lsb)
+ if (cfg->bit.ORDER) {
+ U0GCR |= U0GCR_ORDER;
+ } else {
+ U0GCR &= ~U0GCR_ORDER;
+ }
+
+ // interrupt prio to 1 (0..3=highest)
+ IP0 |= (1<<2);
+ IP1 &= ~(1<<2);
+#else
+ // enable uart mode
+ U1CSR |= 0x80;
+
+ // store config to U1UCR register
+ U1UCR = cfg->byte & (0x7F);
+
+ // store config to U1GCR: (msb/lsb)
+ if (cfg->bit.ORDER) {
+ U1GCR |= U1GCR_ORDER;
+ } else {
+ U1GCR &= ~U1GCR_ORDER;
+ }
+
+ // interrupt prio to 1 (0..3=highest)
+ IP0 |= (1<<3);
+ IP1 &= ~(1<<3);
+#endif // SBUS_UART
+}
+
+void hal_uart_start_transmission(uint8_t *data, uint8_t len) {
+ // important: src addr start is data[1]
+ SET_WORD(hal_dma_config[3].SRCADDRH, hal_dma_config[3].SRCADDRL, &data[1]);
+
+ // configure length of transfer
+ SET_WORD(hal_dma_config[3].LENH, hal_dma_config[3].LENL, len);
+
+ // time to send this frame!
+ // re-arm dma:
+ DMAARM |= DMA_ARM_CH3;
+
+ // 45 nops to make sure the dma config is loaded
+ hal_delay_45nop();
+
+ // send the very first UART byte to trigger a UART TX session:
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ U0DBUF = data[0];
+#else
+ U1DBUF = data[0];
+#endif // SBUS_UART
+}
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+void HAL_UART_RX_ISR(void) {
+ uint8_t rx;
+
+ HAL_UART_RX_ISR_CLEAR_FLAG(); // THIS SHOULD NEVER BE THE LAST LINE IN AN ISR!
+
+#ifdef SBUS_INVERTED
+ rx = 0xFF ^ HAL_UART_RX_GETCH(); // remove data inversion
+#else
+ rx = HAL_UART_RX_GETCH();
+#endif // SBUS_INVERTED
+
+ if (uart_rx_callback != 0) {
+ // execute callback
+ uart_rx_callback(rx);
+ }
+}
+#endif // HUB_TELEMETRY_ON_SBUS_UART
diff --git a/OpenSky/arch/cc251x/hal_uart.h b/OpenSky/arch/cc251x/hal_uart.h
new file mode 100644
index 0000000..51bfcd0
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_uart.h
@@ -0,0 +1,68 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_UART_H_
+#define HAL_UART_H_
+
+#include
+#include "hal_defines.h"
+
+// for a 26MHz Crystal:
+#define CC2510_BAUD_E_115200 12
+#define CC2510_BAUD_M_115200 34
+// best match for 100kbit/s = 99975.5859375 bit/s
+// baudrate = (((256.0 + baud_m)*2.0**baud_e) / (2**28)) * 26000000.0
+#define CC2510_BAUD_E_100000 11
+#define CC2510_BAUD_M_100000 248
+#define CC2510_BAUD_E_57600 11
+#define CC2510_BAUD_M_57600 34
+
+union hal_uart_config_t{
+ uint8_t byte;
+ struct {
+ uint8_t START : 1; // start bit level
+ uint8_t STOP : 1; // stop bit level
+ uint8_t SPB : 1; // stop bits (0=1, 1=2)
+ uint8_t PARITY: 1; // parity (on/off)
+ uint8_t BIT9 : 1; // 9 bit mode
+ uint8_t D9 : 1; // 9th bit level or parity type
+ uint8_t FLOW : 1; // flow control
+ uint8_t ORDER : 1; // data bit order (LSB or MSB first)
+ } bit;
+};
+
+void hal_uart_init(void);
+static void hal_uart_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg);
+void hal_uart_start_transmission(uint8_t *data, uint8_t len);
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
+ #define HAL_UART_RX_ISR(void) hal_uart_rx_interrupt(void) __interrupt URX0_VECTOR
+ #define HAL_UART_RX_ISR_CLEAR_FLAG() { URX0IF = 0; }
+ #define HAL_UART_RX_GETCH() (U0DBUF)
+#else
+ #define HAL_UART_RX_ISR(void) hal_uart_rx_interrupt(void) __interrupt URX1_VECTOR
+ #define HAL_UART_RX_ISR_CLEAR_FLAG() { URX1IF = 0; }
+ #define HAL_UART_RX_GETCH() (U1DBUF)
+#endif // SBUS_UART == ...
+
+ void HAL_UART_RX_ISR(void);
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+
+#endif // HAL_UART_H_
diff --git a/OpenSky/arch/cc251x/hal_wdt.c b/OpenSky/arch/cc251x/hal_wdt.c
new file mode 100644
index 0000000..2b1876d
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_wdt.c
@@ -0,0 +1,50 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_wdt.h"
+#include "debug.h"
+#include "led.h"
+#include "delay.h"
+#include "hal_cc25xx.h"
+
+void hal_wdt_init(void) {
+ // check if 32khz clock source is rcosc:
+ if (!(CLKCON & CLKCON_OSC32K)) {
+ debug("wdt: error! low speed clock not based on int rc");
+ led_green_on();
+ while (1) {
+ led_red_on();
+ delay_ms(200);
+ led_red_off();
+ delay_ms(200);
+ }
+ }
+
+ // set wdt interval to approx 1 second
+ WDCTL = (WDCTL & ~WDCTL_INT) | WDCTL_INT_1S;
+
+ // enable wdt. NOTE: this can not be disabled in software!
+ WDCTL = (WDCTL & ~WDCTL_MODE) | WDCTL_EN;
+}
+
+void hal_wdt_reset(void) {
+ // reset wdt (special sequence)
+ WDCTL = (WDCTL & 0x0F) | 0b10100000;
+ WDCTL = (WDCTL & 0x0F) | 0b01010000;
+}
diff --git a/OpenSky/arch/cc251x/hal_wdt.h b/OpenSky/arch/cc251x/hal_wdt.h
new file mode 100644
index 0000000..d0fee38
--- /dev/null
+++ b/OpenSky/arch/cc251x/hal_wdt.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_WDT_H_
+#define HAL_WDT_H_
+
+void hal_wdt_init(void);
+void hal_wdt_reset(void);
+
+#endif // HAL_WDT_H_
diff --git a/OpenSky/arch/cc251x/portmacros.h b/OpenSky/arch/cc251x/portmacros.h
new file mode 100644
index 0000000..352a3a4
--- /dev/null
+++ b/OpenSky/arch/cc251x/portmacros.h
@@ -0,0 +1,13 @@
+#ifndef __PORTMACROS_H__
+#define __PORTMACROS_H__
+
+
+#define PORT2DIR_(X) X ## DIR
+#define PORT2DIR(PORTNAME) PORT2DIR_(PORTNAME)
+#define PORT2BIT_(X,N) X ## _ ## N
+#define PORT2BIT(PORTNAME, PIN) PORT2BIT_(PORTNAME,PIN)
+#define PORT2INP_(X) X ## INP
+#define PORT2INP(PORTNAME) PORT2INP_(PORTNAME)
+
+
+#endif
diff --git a/OpenSky/arch/rasp/hal_adc.c b/OpenSky/arch/rasp/hal_adc.c
new file mode 100644
index 0000000..405bacd
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_adc.c
@@ -0,0 +1,34 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_adc.h"
+#include "debug.h"
+#include "wdt.h"
+
+
+void hal_adc_init(void) {
+}
+
+void hal_adc_process(void) {
+}
+
+uint8_t hal_adc_get_scaled(uint8_t ch) {
+ return 0;
+}
+
diff --git a/OpenSky/arch/rasp/hal_adc.h b/OpenSky/arch/rasp/hal_adc.h
new file mode 100644
index 0000000..c60ab0f
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_adc.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_ADC_H_
+#define HAL_ADC_H_
+#include "main.h"
+#include
+
+void hal_adc_init(void);
+uint8_t hal_adc_get_scaled(uint8_t ch);
+void hal_adc_process(void);
+
+#endif // HAL_ADC_H_
diff --git a/OpenSky/arch/rasp/hal_cc25xx.c b/OpenSky/arch/rasp/hal_cc25xx.c
new file mode 100644
index 0000000..8aace21
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_cc25xx.c
@@ -0,0 +1,253 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_cc25xx.h"
+#include "hal_spi.h"
+#include "hal_io.h"
+#include "cc25xx.h"
+#include "debug.h"
+#include "timeout.h"
+#include
+#include
+
+void hal_cc25xx_init(void) {
+ hal_spi_init();
+ hal_cc25xx_init_gpio();
+}
+
+static void hal_cc25xx_init_gpio(void) {
+ hal_cc25xx_enter_rxmode();
+}
+
+inline uint32_t hal_cc25xx_set_antenna(uint8_t id) {
+ return id;
+}
+
+const char *registers[] = {
+ "IOCFG2", // 0x00
+ "IOCFG1",
+ "IOCFG0",
+ "FIFOTHR",
+ "SYNC1",
+ "SYNC0",
+ "PKTLEN",
+ "PKTCTRL1",
+ "PKTCTRL0",
+ "ADDR",
+ "CHANNR",
+ "FSCTRL1",
+ "FSCTRL0",
+ "FREQ2",
+ "FREQ1",
+ "FREQ0",
+ "MDMCFG4", // 0x10
+ "MDMCFG3",
+ "MDMCFG2",
+ "MDMCFG1",
+ "MDMCFG0",
+ "DEVIATN",
+ "MCSM2",
+ "MCSM1",
+ "MCSM0",
+ "FOCCFG",
+ "BSCFG",
+ "AGCCTRL2",
+ "AGCCTRL1",
+ "AGCCTRL0",
+ "WOREVT1",
+ "WOREVT0",
+ "WORCTRL", // 0x20
+ "FREND1",
+ "FREND0",
+ "FSCAL3",
+ "FSCAL2",
+ "FSCAL1",
+ "FSCAL0",
+ "RCCTRL1",
+ "RCCTRL0",
+ "FSTEST",
+ "PTEST",
+ "AGCTEST",
+ "TEST2",
+ "TEST1",
+ "TEST0",
+ "RESERVED",
+ "PARTNUM", // 0x30
+ "VERSION",
+ "FREQEST",
+ "LQI",
+ "RSSI",
+ "MARCSTATE",
+ "WORTIME1",
+ "WORTIME0",
+ "PKTSTATUS",
+ "VCO_VC_DAC",
+ "TXBYTES",
+ "RXBYTES",
+ "RCCTRL1_STATUS",
+ "RCCTRL0_STATUS",
+ "PA_TABLE0" // 0x3E
+};
+
+
+inline void hal_cc25xx_set_gdo_mode(void) {
+ cc25xx_set_register(IOCFG0, 0x01); // 6);
+ // cc25xx_set_register(IOCFG1, ???);
+ cc25xx_set_register(IOCFG2, 0x01); // 6);
+}
+
+static int count = 0;
+inline void hal_cc25xx_set_register(uint8_t address, uint8_t data) {
+ uint8_t buffer[2] = {address, data};
+ hal_spi_dma_xfer(buffer, sizeof(buffer));
+ // printf("\nset_register 0x%x (0x%x) '%s' data 0x%x\n", \
+ // address & 0x3f, address, registers[address & 0x3f], data);
+}
+
+inline uint8_t hal_cc25xx_get_register(uint8_t address) {
+ uint8_t buffer[2] = {address | 0x80, 0xff};
+ hal_spi_dma_xfer(buffer, sizeof(buffer));
+ // printf("\nget_register 0x%x (0x%x) '%s' got 0x%x\n", \
+ // address & 0x3f, address, registers[address & 0x3f], buffer[1]);
+ return buffer[1];
+}
+
+static const char *stobes[] = {
+ "RFST_SRES",
+ "RFST_SFSTXON",
+ "RFST_SXOFF",
+ "RFST_SCAL",
+ "RFST_SRX",
+ "RFST_STX",
+ "RFST_SIDLE",
+ "RFST_SWOR",
+ "RFST_SPWD",
+ "RFST_SFRX",
+ "RFST_SFTX",
+ "RFST_SWORRST",
+ "RFST_SNOP"
+};
+
+inline void hal_cc25xx_strobe(uint8_t address) {
+ uint8_t buffer[1] = {address};
+ hal_spi_dma_xfer(buffer, sizeof(buffer));
+
+ // printf("strobe 0x%x '%s' got 0x%x\n", address & 0x3f, stobes[address - 0x30], buffer[0]);
+ // debug("s"); debug_put_hex8(status); debug_put_newline();
+}
+
+uint8_t hal_cc25xx_get_status(void) {
+ uint8_t buffer[2] = {0xff, 0xff};
+ hal_spi_dma_xfer(buffer, sizeof(buffer));
+ return buffer[1];
+}
+
+uint8_t hal_cc25xx_transmission_completed(void) {
+ return 1; // return ((hal_cc25xx_get_status() & (0x70)) == CC2500_STATUS_STATE_RX);
+}
+
+inline void hal_cc25xx_enter_rxmode(void) {
+ hal_io_set_amp(0);
+}
+
+inline void hal_cc25xx_enter_txmode(void) {
+ hal_io_set_amp(1);
+}
+
+
+inline void hal_cc25xx_enable_receive(void) {
+ // switch on rx again
+ hal_cc25xx_enter_rxmode();
+}
+
+
+inline void hal_cc25xx_read_fifo(uint8_t *buf, uint8_t len) {
+ hal_cc25xx_register_read_multi(CC25XX_FIFO | READ_FLAG | BURST_FLAG, buf, len);
+}
+
+inline void hal_cc25xx_register_read_multi(uint8_t address, uint8_t *buffer, uint8_t len) {
+ uint8_t buffer2[len + 1];
+ buffer2[0] = address;
+ memset(buffer2+1, 0xFF, len);
+ hal_spi_dma_xfer(buffer2, len+1);
+ memcpy(buffer, buffer2+1, len);
+}
+
+inline void hal_cc25xx_register_write_multi(uint8_t address, uint8_t *buffer, uint8_t len) {
+ uint8_t buffer2[len + 1];
+ buffer2[0] = address | BURST_FLAG;
+ memcpy(buffer2+1, buffer, len);
+ hal_spi_dma_xfer(buffer2, len+1);
+}
+
+inline void hal_cc25xx_process_packet(volatile uint8_t *packet_received,
+ volatile uint8_t *buffer, uint8_t maxlen) {
+ if (hal_spi_get_gdo0() == 1) {
+ // data received, fetch data
+ // timeout_set_100us(5);
+
+ *packet_received = 0;
+
+ // there is a bug in the cc2500
+ // see p3 http:// www.ti.com/lit/er/swrz002e/swrz002e.pdf
+ // workaround: read len register very quickly twice:
+ uint8_t len1, len2, len, i;
+
+ // try this 10 times befor giving up:
+ for (i = 0; i < 10; i++) {
+ len1 = hal_cc25xx_get_register_burst(RXBYTES) & 0x7F;
+ len2 = hal_cc25xx_get_register_burst(RXBYTES) & 0x7F;
+ if (len1 == len2) break;
+ }
+
+ // valid len found?
+ if (len1 == len2 && len1 > 0) {
+ // debug("process_packet got: "); debug_put_uint8(len1);
+ // debug(" expecting: "); debug_put_uint8(maxlen);
+ len = len1;
+
+ // packet received, grab data
+ uint8_t tmp_buffer[len];
+ hal_cc25xx_read_fifo(tmp_buffer, len);
+
+ // only accept valid packet lenbghts:
+ if (len == maxlen) {
+ uint8_t i;
+ for (i = 0; i < maxlen; i++) {
+ buffer[i] = tmp_buffer[i];
+ }
+ *packet_received = 1;
+ // debug(" OK");
+ }
+ // debug("\n"); debug_flush();
+ } else {
+ // no, ignore this
+ len = 0;
+ }
+ }
+}
+
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len) {
+ // flush tx fifo
+ hal_cc25xx_strobe(RFST_SFTX);
+ // copy to fifo
+ hal_cc25xx_register_write_multi(CC25XX_FIFO, (uint8_t *)buffer, buffer[0]+1);
+ // and send!
+ hal_cc25xx_strobe(RFST_STX);
+}
diff --git a/OpenSky/arch/rasp/hal_cc25xx.h b/OpenSky/arch/rasp/hal_cc25xx.h
new file mode 100644
index 0000000..175a386
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_cc25xx.h
@@ -0,0 +1,188 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_CC25XX_H_
+#define HAL_CC25XX_H_
+
+#include
+
+
+
+void hal_cc25xx_init(void);
+void hal_cc25xx_set_register(uint8_t reg, uint8_t val);
+uint8_t hal_cc25xx_get_register(uint8_t address);
+void hal_cc25xx_strobe(uint8_t val);
+
+void hal_cc25xx_enable_receive(void);
+void hal_cc25xx_enable_transmit(void);
+void hal_cc25xx_enter_rxmode(void);
+void hal_cc25xx_enter_txmode(void);
+
+#define hal_cc25xx_rx_sleep() { delay_us(1352); }
+#define hal_cc25xx_tx_sleep() { delay_us(1250); }
+
+// not used on d4rii
+#define hal_cc25xx_disable_rf_interrupt() {}
+#define hal_cc25xx_setup_rf_dma(mode) {}
+#define hal_cc25xx_partnum_valid(p, v) ((p == 0x80) && (v = 0x03))
+
+uint8_t hal_cc25xx_get_status(void);
+static void hal_cc25xx_init_gpio(void);
+uint32_t hal_cc25xx_set_antenna(uint8_t id);
+void hal_cc25xx_set_gdo_mode(void);
+uint8_t hal_cc25xx_get_gdo_status(void);
+void hal_cc25xx_process_packet(volatile uint8_t *packet_received,
+ volatile uint8_t *buffer, uint8_t maxlen);
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len);
+
+void hal_cc25xx_read_fifo(uint8_t *buf, uint8_t len);
+void hal_cc25xx_register_read_multi(uint8_t address, uint8_t *buffer, uint8_t len);
+uint8_t hal_cc25xx_transmission_completed(void);
+
+// adress checks
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_00 ((0<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_01 ((0<<1) | (1<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_10 ((1<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_11 ((1<<1) | (1<<0))
+// append status bytes?
+#define CC2500_PKTCTRL1_APPEND_STATUS (1<<2)
+// crc autoflush
+#define CC2500_PKTCTRL1_CRC_AUTOFLUSH (1<<3)
+
+// Flags
+#define BURST_FLAG 0b01000000
+#define WRITE_FLAG 0b00000000
+#define READ_FLAG 0b10000000
+
+// Definitions for burst/single access to registers
+#define CC2500_WRITE_SINGLE 0x00
+#define CC2500_WRITE_BURST 0x40
+#define CC2500_READ_SINGLE 0x80
+#define CC2500_READ_BURST 0xC0
+
+#define CC2500_STATUS_STATE_IDLE (0<<4)
+#define CC2500_STATUS_STATE_RX (1<<4)
+#define CC2500_STATUS_STATE_TX (2<<4)
+#define CC2500_STATUS_STATE_FSTXON (3<<4)
+#define CC2500_STATUS_STATE_CALIBRATE (4<<4)
+#define CC2500_STATUS_STATE_SETTLING (5<<4)
+#define CC2500_STATUS_STATE_RXFIFO_OVF (6<<4)
+#define CC2500_STATUS_STATE_TXFIFO_OVF (7<<4)
+
+#define hal_cc25xx_get_register_burst(x) hal_cc25xx_get_register(x | READ_FLAG | BURST_FLAG)
+
+
+// strobes
+#define RFST_SRES 0x30
+#define RFST_SFSTXON 0x31
+#define RFST_SXOFF 0x32
+#define RFST_SCAL 0x33
+#define RFST_SRX 0x34
+#define RFST_STX 0x35
+#define RFST_SIDLE 0x36
+#define RFST_SWOR 0x38
+#define RFST_SPWD 0x39
+#define RFST_SFRX 0x3A
+#define RFST_SFTX 0x3B
+#define RFST_SWORRST 0x3C
+#define RFST_SNOP 0x3D
+
+// Status registers
+#define PARTNUM 0x30|BURST_FLAG
+#define VERSION 0x31|BURST_FLAG
+#define FREQEST 0x32|BURST_FLAG
+#define LQI 0x33|BURST_FLAG
+#define RSSI 0x34|BURST_FLAG
+#define MARCSTATE 0x35|BURST_FLAG
+#define WORTIME1 0x36|BURST_FLAG
+#define WORTIME0 0x37|BURST_FLAG
+#define PKTSTATUS 0x38|BURST_FLAG
+#define VCO_VC_DAC 0x39|BURST_FLAG
+#define TXBYTES 0x3A|BURST_FLAG
+#define RXBYTES 0x3B|BURST_FLAG
+#define RCCTRL1_STATUS 0x3C|BURST_FLAG
+#define RCCTRL0_STATUS 0x3D|BURST_FLAG
+
+// Status byte states
+#define STB_IDLE 0x00
+#define STB_RX 0x10
+#define STB_TX 0x20
+#define STB_FSTXON 0x30
+#define STB_CALIBRATE 0x40
+#define STB_SETTLING 0x50
+#define STB_RX_OVF 0x60
+#define STB_TX_UNDF 0x70
+
+// Config registers addresses
+#define IOCFG2 0x00
+#define IOCFG1 0x01
+#define IOCFG0 0x02
+#define FIFOTHR 0x03
+#define SYNC1 0x04
+#define SYNC0 0x05
+#define PKTLEN 0x06
+#define PKTCTRL1 0x07
+#define PKTCTRL0 0x08
+#define ADDR 0x09
+#define CHANNR 0x0A
+#define FSCTRL1 0x0B
+#define FSCTRL0 0x0C
+#define FREQ2 0x0D
+#define FREQ1 0x0E
+#define FREQ0 0x0F
+#define MDMCFG4 0x10
+#define MDMCFG3 0x11
+#define MDMCFG2 0x12
+#define MDMCFG1 0x13
+#define MDMCFG0 0x14
+#define DEVIATN 0x15
+#define MCSM2 0x16
+#define MCSM1 0x17
+#define MCSM0 0x18
+#define FOCCFG 0x19
+#define BSCFG 0x1A
+#define AGCCTRL2 0x1B
+#define AGCCTRL1 0x1C
+#define AGCCTRL0 0x1D
+#define WOREVT1 0x1E
+#define WOREVT0 0x1F
+#define WORCTRL 0x20
+#define FREND1 0x21
+#define FREND0 0x22
+#define FSCAL3 0x23
+#define FSCAL2 0x24
+#define FSCAL1 0x25
+#define FSCAL0 0x26
+#define RCCTRL1 0x27
+#define RCCTRL0 0x28
+#define FSTEST 0x29
+#define PTEST 0x2A
+#define AGCTEST 0x2B
+#define TEST2 0x2C
+#define TEST1 0x2D
+#define TEST0 0x2E
+
+#define PA_TABLE0 0x3E
+
+// FIFO
+#define CC25XX_FIFO 0x3F
+
+
+#endif // HAL_CC25XX_H_
+
diff --git a/OpenSky/arch/rasp/hal_clocksource.h b/OpenSky/arch/rasp/hal_clocksource.h
new file mode 100644
index 0000000..27dc3fc
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_clocksource.h
@@ -0,0 +1,7 @@
+#ifndef __HAL_CLOCKSOURCE_H__
+#define __HAL_CLOCKSOURCE_H__
+
+// no necessary for stm32, it is done in system startup
+#define hal_clocksource_init() {}
+
+#endif // __HAL_CLOCKSOURCE_H__
diff --git a/OpenSky/arch/rasp/hal_debug.c b/OpenSky/arch/rasp/hal_debug.c
new file mode 100644
index 0000000..d0fea49
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_debug.c
@@ -0,0 +1,56 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_debug.h"
+#include "debug.h"
+#include "led.h"
+
+#include
+#include
+#include
+
+void hal_debug_init(void) {
+}
+
+void hal_debug_init_nvic(uint8_t enable) {
+}
+
+
+static void hal_debug_init_mode(void) {
+}
+
+static void hal_debug_enable(void) {
+}
+
+void hal_debug_start_transmission(uint8_t ch) {
+ fwrite(&ch, 1, 1, stdout);
+}
+
+void hal_debug_int_enable(void) {
+}
+
+uint8_t hal_debug_int_enabled(void) {
+ return 0;
+}
+
+static void hal_debug_init_gpio(void) {
+}
+
+static void hal_debug_init_rcc(void) {
+}
diff --git a/OpenSky/arch/rasp/hal_debug.h b/OpenSky/arch/rasp/hal_debug.h
new file mode 100644
index 0000000..654171a
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_debug.h
@@ -0,0 +1,37 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DEBUG_H_
+#define HAL_DEBUG_H_
+
+#include
+
+void hal_debug_init(void);
+void hal_debug_start_transmission(uint8_t ch);
+uint8_t hal_debug_int_enabled(void);
+void hal_debug_int_enable(void);
+#define hal_debug_int_disable() {}
+#define DEBUG_ISR(void) hal_debug_tx_interrupt(void)
+#define HAL_DEBUG_ISR_FLAG_SET() (1)
+#define HAL_DEBUG_ISR_CLEAR_FLAG() { }
+#define HAL_DEBUG_ISR_DISABLE() { }
+#define HAL_DEBUG_TX_DATA(data) { }
+
+
+#endif // HAL_DEBUG_H_
diff --git a/OpenSky/arch/rasp/hal_defines.h b/OpenSky/arch/rasp/hal_defines.h
new file mode 100644
index 0000000..c92079f
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_defines.h
@@ -0,0 +1,15 @@
+#ifndef __HAL_DEFINES_H__
+#define __HAL_DEFINES_H__
+
+#define EXTERNAL_MEMORY
+#define EXTERNAL_DATA
+
+#define HI(a) (uint8_t) ((uint16_t)(a) >> 8 )
+#define LO(a) (uint8_t) (uint16_t)(a)
+#define SET_WORD(H, L, val) { (H) = HI(val); (L) = LO(val); }
+// necessary for timer registers. todo: check if necessary for others as well...
+#define SET_WORD_LO_FIRST(H, L, val) {(L) = LO(val); (H) = HI(val); }
+
+#define UNUSED(x) (void)(x);
+
+#endif // __HAL_DEFINES_H__
diff --git a/OpenSky/arch/rasp/hal_delay.h b/OpenSky/arch/rasp/hal_delay.h
new file mode 100644
index 0000000..1c4bdf4
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_delay.h
@@ -0,0 +1,9 @@
+#ifndef __HAL_DELAY_H__
+#define __HAL_DELAY_H__
+#include "hal_timeout.h"
+
+#define hal_delay_us(us) hal_timeout_delay_us(us)
+#define hal_delay_ms(ms) hal_timeout_delay_us((ms) * 1000)
+
+
+#endif // __HAL_DELAY_H__
diff --git a/OpenSky/arch/rasp/hal_dma.h b/OpenSky/arch/rasp/hal_dma.h
new file mode 100644
index 0000000..1c305b0
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_dma.h
@@ -0,0 +1 @@
+/* not used by rasp */
\ No newline at end of file
diff --git a/OpenSky/arch/rasp/hal_io.c b/OpenSky/arch/rasp/hal_io.c
new file mode 100644
index 0000000..f822c60
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_io.c
@@ -0,0 +1,133 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_io.h"
+#include "hal_cc25xx.h"
+#include "delay.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define BLOCK_SIZE (4*1024)
+
+// I/O access
+volatile static unsigned *gpio;
+
+// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7 << (((g) % 10)*3))
+#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1 << (((g)% 10)*3))
+#define SET_GPIO_ALT(g, a) *(gpio+(((g)/10))) |= \
+ (((a) <= 3 ? (a) + 4:(a) == 4 ? 3 : 2) << (((g) % 10) * 3))
+
+#define GPIO_SET *(gpio + 7) // sets bits which are 1 ignores bits which are 0
+#define GPIO_CLR *(gpio + 10) // clears bits which are 1 ignores bits which are 0
+
+#define GET_GPIO(g) (*(gpio + 13) & (1 << g)) // 0 if LOW, (1< gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_IO_H_
+#define HAL_IO_H_
+
+#include
+
+void hal_io_init(void);
+uint8_t hal_io_bind_request(void);
+int hal_spi_get_gdo0(void);
+
+#define HAL_PA 1
+#define HAL_LNA 0
+
+void hal_io_set_amp(int pa);
+void hal_io_set_ppm(int state);
+
+#endif // HAL_IO_H_
diff --git a/OpenSky/arch/rasp/hal_led.h b/OpenSky/arch/rasp/hal_led.h
new file mode 100644
index 0000000..7f0c0b9
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_led.h
@@ -0,0 +1,19 @@
+#ifndef __HAL_LED__H_
+#define __HAL_LED__H_
+
+#include
+
+void hal_led_init(uint16_t pin);
+
+#define hal_led_green_init() {}
+#define hal_led_green_on() {}
+#define hal_led_green_off() {}
+#define hal_led_green_toggle() {}
+
+#define hal_led_red_init() {}
+#define hal_led_red_on() {}
+#define hal_led_red_off() {}
+#define hal_led_red_toggle() {}
+
+#endif // __HAL_LED__H_
+
diff --git a/OpenSky/arch/rasp/hal_ppm.c b/OpenSky/arch/rasp/hal_ppm.c
new file mode 100644
index 0000000..e6ac396
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_ppm.c
@@ -0,0 +1,71 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_ppm.h"
+#include "hal_io.h"
+#include "hal_timeout.h"
+#include "ppm.h"
+#include "wdt.h"
+#include "led.h"
+
+#if SBUS_ENABLED == 1
+void hal_ppm_init(void) {
+}
+void hal_ppm_tick() {
+}
+#else
+
+static int state = 1;
+static int failsafe = 0;
+
+void hal_ppm_init(void) {
+ hal_io_set_ppm(state);
+}
+
+void hal_ppm_failsafe_enter(void) {
+ failsafe = 1;
+}
+
+void hal_ppm_failsafe_exit(void) {
+ failsafe = 0;
+}
+
+void hal_ppm_update_cvalue(int us) {
+ // Keep singal up, until the last 200ms of the count.
+ hal_timeout_add_ppm(us - HAL_PPM_US_TO_TICKCOUNT(200));
+}
+
+void hal_ppm_tick() {
+ if (state == 1) {
+ state = 0;
+ if (!failsafe)
+ hal_io_set_ppm(state);
+ // Then lower the signal for another 200ms..
+ hal_timeout_add_ppm(HAL_PPM_US_TO_TICKCOUNT(200));
+ } else {
+ state = 1;
+ if (!failsafe)
+ hal_io_set_ppm(state);
+
+ // Call the code, that will call hal_ppm_update_cvalue back to us.
+ hal_ppm_irq_callback();
+ }
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/rasp/hal_ppm.h b/OpenSky/arch/rasp/hal_ppm.h
new file mode 100644
index 0000000..4a6bc72
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_ppm.h
@@ -0,0 +1,43 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_PPM_H_
+#define HAL_PPM_H_
+
+void hal_ppm_init(void);
+
+void hal_ppm_failsafe_exit(void);
+void hal_ppm_failsafe_enter(void);
+void hal_ppm_tick();
+void hal_ppm_update_cvalue(int us);
+
+void hal_ppm_irq_callback(void);
+
+#define HAL_PPM_US_TO_TICKCOUNT(us) ((us * 1)-1)
+#define HAL_PPM_FRSKY_TO_TICKCOUNT(_frsky) ((_frsky)*2*2/3)
+
+#define PPM_TIMER_ISR(void) hal_ppm_irq_callback(void)
+
+#define HAL_PPM_UPDATE_CCVALUE(x) hal_ppm_update_cvalue(x)
+#define HAL_PPM_ISR_DISABLE() { }
+#define HAL_PPM_ISR_ENABLE() { }
+#define HAL_PPM_ISR_FLAG_SET() (1)
+#define HAL_PPM_ISR_CLEAR_FLAG() {}
+
+#endif // HAL_PPM_H_
diff --git a/OpenSky/arch/rasp/hal_sbus.c b/OpenSky/arch/rasp/hal_sbus.c
new file mode 100644
index 0000000..8630d69
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_sbus.c
@@ -0,0 +1,66 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include
+#include // Used for UART
+#include // Used for UART
+#include // Used for UART
+
+#include "hal_sbus.h"
+#include "debug.h"
+#include "delay.h"
+#include "sbus.h"
+
+#if SBUS_ENABLED
+
+static int uart0_filestream = -1;
+
+void hal_sbus_init(EXTERNAL_MEMORY uint8_t *sbus_data_ptr) {
+ // open in non blocking read/write mode
+ uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
+ if (uart0_filestream == -1) {
+ printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
+ }
+
+ // USART configuration:
+ // 100000bps inverted serial stream, 8 bits, even parity, 2 stop bits
+ // no hw flow control
+ struct termios2 options;
+ options.c_cflag = BOTHER | CS8 | CLOCAL | PARENB | CSTOPB;
+ options.c_iflag = 0;
+ options.c_oflag = 0;
+ options.c_lflag = 0;
+ options.c_ispeed = 100000;
+ options.c_ospeed = 100000;
+ if (ioctl(uart0_filestream, TCSETS2, &options) != 0) {
+ printf("ioctl TCSETS2 failed");
+ }
+}
+
+void hal_sbus_start_transmission(uint8_t *data, uint8_t len) {
+ if (uart0_filestream != -1) {
+ int count = write(uart0_filestream, data, len);
+ if (count < len) {
+ printf("UART TX error sent %u of %u\n", count, len);
+ }
+ // printf("%d bytes written\n", len);
+ }
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/rasp/hal_sbus.h b/OpenSky/arch/rasp/hal_sbus.h
new file mode 100644
index 0000000..6f265ac
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_sbus.h
@@ -0,0 +1,38 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SBUS_H_
+#define HAL_SBUS_H_
+
+#include
+#include "hal_defines.h"
+
+void hal_sbus_init(EXTERNAL_MEMORY uint8_t *data_ptr);
+void hal_sbus_start_transmission(uint8_t *buffer, uint8_t len);
+
+// this helper routine will invert the data
+// stored in buffer in case the sbus is set
+// to inverted
+#if SBUS_INVERTED
+#define HAL_SBUS_PREPARE_DATA(a) (0xFF ^ (a))
+#else
+#define HAL_SBUS_PREPARE_DATA(a) (a)
+#endif // SBUS_INVERTED
+
+#endif // HAL_SBUS_H_
diff --git a/OpenSky/arch/rasp/hal_soft_serial.c b/OpenSky/arch/rasp/hal_soft_serial.c
new file mode 100644
index 0000000..ce7bc80
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_soft_serial.c
@@ -0,0 +1,32 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_soft_serial.h"
+#include "soft_serial.h"
+#include "debug.h"
+#include "delay.h"
+#include "led.h"
+#include "wdt.h"
+#include "config.h"
+#include "hal_cc25xx.h"
+
+
+void hal_soft_serial_init(void) {
+}
+
diff --git a/OpenSky/arch/rasp/hal_soft_serial.h b/OpenSky/arch/rasp/hal_soft_serial.h
new file mode 100644
index 0000000..87211ed
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_soft_serial.h
@@ -0,0 +1,31 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SOFT_SERIAL_H_
+#define HAL_SOFT_SERIAL_H_
+
+#include "soft_serial.h"
+#include "config.h"
+
+void hal_soft_serial_init(void);
+
+#define HUB_TELEMETRY_PIN_LO() (0)
+#define HUB_TELEMETRY_PIN_HI() (!HUB_TELEMETRY_PIN_LO())
+
+#endif // HAL_SOFT_SERIAL_H_
diff --git a/OpenSky/arch/rasp/hal_spi.c b/OpenSky/arch/rasp/hal_spi.c
new file mode 100644
index 0000000..e276572
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_spi.c
@@ -0,0 +1,118 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "hal_spi.h"
+
+static void pabort(const char *s) {
+ perror(s);
+ abort();
+}
+
+static const char *device = "/dev/spidev0.0";
+static uint8_t bits = 8;
+static uint32_t speed = 1000000;
+static int fd = -1;
+static uint32_t mode = 0;
+static uint16_t delay = 20;
+
+void hal_spi_init(void) {
+ int ret = 0;
+
+ /*
+ * Open device
+ */
+ fd = open(device, O_RDWR);
+ if (fd < 0)
+ pabort("can't open device");
+
+ /*
+ * spi mode
+ */
+ ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
+ if (ret == -1)
+ pabort("can't set spi mode");
+
+ ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
+ if (ret == -1)
+ pabort("can't get spi mode");
+
+ /*
+ * bits per word
+ */
+ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
+ if (ret == -1)
+ pabort("can't set bits per word");
+
+ ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
+ if (ret == -1)
+ pabort("can't get bits per word");
+
+ /*
+ * max speed hz
+ */
+ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+ if (ret == -1)
+ pabort("can't set max speed hz");
+
+ ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
+ if (ret == -1)
+ pabort("can't get max speed hz");
+
+ printf("spi: mode: 0x%x\n", mode);
+ printf("spi: bits per word: %d\n", bits);
+ printf("spi: max speed: %d Hz (%f MHz)\n", speed, speed/1000000.0);
+}
+
+void hal_spi_dma_xfer(uint8_t *buffer, uint8_t len) {
+ int ret;
+ uint8_t rx;
+#if LOG_SPI
+ int i;
+ for (i=0; i < len; i++)
+ fprintf(stderr, "> %x\n", buffer[i]);
+#endif // LOG_SPI
+ struct spi_ioc_transfer tr = {
+ .tx_buf = (uint64_t)buffer,
+ .rx_buf = (uint64_t)buffer,
+ .len = len,
+ .delay_usecs = delay,
+ .speed_hz = speed,
+ .bits_per_word = bits,
+ };
+
+ ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
+ if (ret < 1)
+ pabort("can't send spi message");
+#if LOG_SPI
+ for (i=0; i < len; i++)
+ fprintf(stderr, "< %x\n", buffer[i]);
+ fprintf(stderr, "\n");
+#endif // LOG_SPI
+}
diff --git a/OpenSky/arch/rasp/hal_spi.h b/OpenSky/arch/rasp/hal_spi.h
new file mode 100644
index 0000000..c13c978
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_spi.h
@@ -0,0 +1,30 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SPI_H_
+#define HAL_SPI_H_
+#include
+#include "config.h"
+#include "delay.h"
+
+void hal_spi_init(void);
+void hal_spi_dma_xfer(uint8_t *buffer, uint8_t len);
+
+#endif // HAL_SPI_H_
+
diff --git a/OpenSky/arch/rasp/hal_storage.c b/OpenSky/arch/rasp/hal_storage.c
new file mode 100644
index 0000000..3029ef5
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_storage.c
@@ -0,0 +1,49 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_storage.h"
+#include "debug.h"
+#include "main.h"
+#include "delay.h"
+#include "wdt.h"
+
+#include
+#include
+
+void hal_storage_init(void) {
+ debug("hal_storage: init\n"); debug_flush();
+}
+
+void hal_storage_write(uint8_t *buffer, uint16_t len) {
+ FILE *f = fopen("flash_storage.bin", "w");
+ fwrite(buffer, len, 1, f);
+ fclose(f);
+}
+
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len) {
+ FILE *f = fopen("flash_storage.bin", "r");
+ if (!f) {
+ memset(storage_ptr, 0, len);
+ return;
+ }
+ fread(storage_ptr, len, 1, f);
+ fclose(f);
+}
+
+
diff --git a/OpenSky/arch/rasp/hal_storage.h b/OpenSky/arch/rasp/hal_storage.h
new file mode 100644
index 0000000..5f7f5c4
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_storage.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_STORAGE_H_
+#define HAL_STORAGE_H_
+#include
+#include "config.h"
+
+void hal_storage_init(void);
+void hal_storage_write(uint8_t *buffer, uint16_t len);
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len);
+
+#endif // HAL_STORAGE_H_
diff --git a/OpenSky/arch/rasp/hal_timeout.c b/OpenSky/arch/rasp/hal_timeout.c
new file mode 100644
index 0000000..6264177
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_timeout.c
@@ -0,0 +1,154 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_timeout.h"
+#include "hal_ppm.h"
+#include "debug.h"
+#include "wdt.h"
+
+#include
+#include
+#include
+
+struct timespec timer_1;
+struct timespec timer_2;
+struct timespec timer_ppm;
+
+void hal_timeout_init(void) {
+ memset(&timer_1, 0, sizeof(timer_1));
+ memset(&timer_2, 0, sizeof(timer_2));
+ clock_gettime(CLOCK_REALTIME, &timer_ppm);
+}
+
+/* Returns true if a is greather then b */
+static inline uint8_t timeval_gt(const struct timespec *a, const struct timespec *b) {
+ if (a->tv_sec > b->tv_sec)
+ return 1;
+ if (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec)
+ return 1;
+ return 0;
+}
+
+static inline void timer_add(struct timespec *timer, int us) {
+ timer->tv_nsec += us * 1000;
+ if (timer->tv_nsec > 1000000000) {
+ timer->tv_nsec -= 1000000000;
+ timer->tv_sec += 1;
+ }
+}
+
+/* Subtract the ‘struct timeval’ values X and Y,
+ storing the result in RESULT.
+ Return 1 if the difference is negative, otherwise 0. */
+static inline int timeval_subtract(struct timespec *result,
+ struct timespec *x, struct timespec *y) {
+ /* Perform the carry for the later subtraction by updating y. */
+ if (x->tv_nsec < y->tv_nsec) {
+ int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+ y->tv_nsec -= 1000000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if (x->tv_nsec - y->tv_nsec > 1000000000) {
+ int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
+ y->tv_nsec += 1000000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /* Compute the time remaining to wait.
+ tv_nsec is certainly positive. */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}
+
+void hal_timeout_set_100us(uint32_t hus) {
+ clock_gettime(CLOCK_REALTIME, &timer_1);
+ timer_add(&timer_1, hus * 100);
+}
+
+void hal_timeout2_set_100us(uint32_t hus) {
+ clock_gettime(CLOCK_REALTIME, &timer_2);
+ timer_add(&timer_2, hus * 100);
+}
+
+void hal_timeout_set(uint32_t ms) {
+ clock_gettime(CLOCK_REALTIME, &timer_1);
+ timer_add(&timer_1, ms * 1000);
+}
+
+
+uint8_t hal_timeout_timed_out(void) {
+ struct timespec now;
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ if (timeval_gt(&now, &timer_ppm)) {
+ hal_ppm_tick();
+ }
+
+ return timeval_gt(&now, &timer_1);
+}
+
+uint8_t hal_timeout2_timed_out(void) {
+ struct timespec now;
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ if (timeval_gt(&now, &timer_ppm)) {
+ hal_ppm_tick();
+ }
+ return timeval_gt(&now, &timer_2);
+}
+
+void hal_timeout_delay_us(int32_t timeout_us) {
+ struct timespec now, sleep, delay_timer, rem;
+ clock_gettime(CLOCK_REALTIME, &now);
+ memcpy(&delay_timer, &now, sizeof(struct timespec));
+ timer_add(&delay_timer, timeout_us);
+
+ do {
+ /* If ppm happens before delay timer times out. (delay_timer gt timer_ppm) */
+ if (timeval_gt(&delay_timer, &timer_ppm)) {
+ /* Calculate how far to sleep */
+ if (timeval_subtract(&sleep, &now, &timer_ppm) > 0) {
+ nanosleep(&sleep, &rem);
+ }
+
+ /* Get current time again */
+ clock_gettime(CLOCK_REALTIME, &now);
+ if (timeval_gt(&now, &timer_ppm)) {
+ hal_ppm_tick();
+ }
+
+ /* Loop, as a new ppm timer might be scheduled again before the delay ends */
+ continue;
+ }
+
+ /* Calculate how long to sleep */
+ if (timeval_subtract(&sleep, &now, &delay_timer) > 0) {
+ nanosleep(&sleep, &rem);
+ }
+ } while (0);
+}
+
+void hal_timeout_add_ppm(uint32_t us) {
+ timer_add(&timer_ppm, us);
+}
+
+
diff --git a/OpenSky/arch/rasp/hal_timeout.h b/OpenSky/arch/rasp/hal_timeout.h
new file mode 100644
index 0000000..64bb333
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_timeout.h
@@ -0,0 +1,40 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_TIMEOUT_H_
+#define HAL_TIMEOUT_H_
+
+#include
+
+void hal_timeout_init(void);
+void hal_timeout_set(uint32_t ms);
+void hal_timeout_set_100us(uint32_t hus);
+uint8_t hal_timeout_timed_out(void);
+void hal_timeout_delay_us(int32_t timeout);
+
+void hal_timeout2_set(uint32_t ms);
+void hal_timeout2_set_100us(uint32_t hus);
+uint8_t hal_timeout2_timed_out(void);
+void hal_timeout_add_ppm(uint32_t us);
+
+// void hal_timeout_delay_100us(uint32_t timeout);
+uint32_t hal_timeout_time_remaining(void);
+
+
+#endif // HAL_TIMEOUT_H_
diff --git a/OpenSky/arch/rasp/hal_uart.c b/OpenSky/arch/rasp/hal_uart.c
new file mode 100644
index 0000000..17027ef
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_uart.c
@@ -0,0 +1,66 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include
+#include // Used for UART
+#include // Used for UART
+#include // Used for UART
+
+#include "hal_uart.h"
+#include "debug.h"
+#include "delay.h"
+#include "sbus.h"
+
+#if SBUS_ENABLED
+
+static int uart0_filestream = -1;
+
+void hal_uart_init(EXTERNAL_MEMORY uint8_t *sbus_data_ptr) {
+ // Open in non blocking read/write mode
+ uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
+ if (uart0_filestream == -1) {
+ printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
+ }
+
+ // USART configuration:
+ // 100000bps inverted serial stream, 8 bits, even parity, 2 stop bits
+ // no hw flow control
+ struct termios2 options;
+ options.c_cflag = BOTHER | CS8 | CLOCAL | PARENB | CSTOPB;
+ options.c_iflag = 0;
+ options.c_oflag = 0;
+ options.c_lflag = 0;
+ options.c_ispeed = 100000;
+ options.c_ospeed = 100000;
+ if (ioctl(uart0_filestream, TCSETS2, &options) != 0) {
+ printf("ioctl TCSETS2 failed");
+ }
+}
+
+void hal_uart_start_transmission(uint8_t *data, uint8_t len) {
+ if (uart0_filestream != -1) {
+ int count = write(uart0_filestream, data, len);
+ if (count < len) {
+ printf("UART TX error sent %u of %u\n", count, len);
+ }
+ // printf("%d bytes written\n", len);
+ }
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/rasp/hal_uart.h b/OpenSky/arch/rasp/hal_uart.h
new file mode 100644
index 0000000..f6deb18
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_uart.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_UART_H_
+#define HAL_UART_H_
+
+#include
+#include "hal_defines.h"
+
+void hal_uart_init(EXTERNAL_MEMORY uint8_t *data_ptr);
+void hal_uart_start_transmission(uint8_t *buffer, uint8_t len);
+
+#endif // HAL_UART_H_
diff --git a/OpenSky/arch/rasp/hal_wdt.c b/OpenSky/arch/rasp/hal_wdt.c
new file mode 100644
index 0000000..ccacf16
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_wdt.c
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_wdt.h"
+#include "debug.h"
+#include "delay.h"
+
+void hal_wdt_init(void) {
+}
+
+inline void hal_wdt_reset(void) {
+}
+
diff --git a/OpenSky/arch/rasp/hal_wdt.h b/OpenSky/arch/rasp/hal_wdt.h
new file mode 100644
index 0000000..d0fee38
--- /dev/null
+++ b/OpenSky/arch/rasp/hal_wdt.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_WDT_H_
+#define HAL_WDT_H_
+
+void hal_wdt_init(void);
+void hal_wdt_reset(void);
+
+#endif // HAL_WDT_H_
diff --git a/OpenSky/arch/stm32f1/core/core_cm3.c b/OpenSky/arch/stm32f1/core/core_cm3.c
new file mode 100644
index 0000000..b79d246
--- /dev/null
+++ b/OpenSky/arch/stm32f1/core/core_cm3.c
@@ -0,0 +1,784 @@
+/**************************************************************************// **
+ * @file core_cm3.c
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
+ * @version V1.30
+ * @date 30. October 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#include
+
+/* define compiler specific symbols */
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+__ASM uint32_t __get_PSP(void)
+{
+ mrs r0, psp
+ bx lr
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+__ASM void __set_PSP(uint32_t topOfProcStack)
+{
+ msr psp, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+__ASM uint32_t __get_MSP(void)
+{
+ mrs r0, msp
+ bx lr
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+__ASM void __set_MSP(uint32_t mainStackPointer)
+{
+ msr msp, r0
+ bx lr
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+__ASM uint32_t __REV16(uint16_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+__ASM int32_t __REVSH(int16_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+__ASM void __CLREX(void)
+{
+ clrex
+}
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @return BasePriority
+ *
+ * Return the content of the base priority register
+ */
+__ASM uint32_t __get_BASEPRI(void)
+{
+ mrs r0, basepri
+ bx lr
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param basePri BasePriority
+ *
+ * Set the base priority register
+ */
+__ASM void __set_BASEPRI(uint32_t basePri)
+{
+ msr basepri, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+__ASM uint32_t __get_PRIMASK(void)
+{
+ mrs r0, primask
+ bx lr
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+__ASM void __set_PRIMASK(uint32_t priMask)
+{
+ msr primask, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @return FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+__ASM uint32_t __get_FAULTMASK(void)
+{
+ mrs r0, faultmask
+ bx lr
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param faultMask faultMask value
+ *
+ * Set the fault mask register
+ */
+__ASM void __set_FAULTMASK(uint32_t faultMask)
+{
+ msr faultmask, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @return Control value
+ *
+ * Return the content of the control register
+ */
+__ASM uint32_t __get_CONTROL(void)
+{
+ mrs r0, control
+ bx lr
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+__ASM void __set_CONTROL(uint32_t control)
+{
+ msr control, r0
+ bx lr
+}
+
+#endif /* __ARMCC_VERSION */
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+#pragma diag_suppress=Pe940
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+uint32_t __get_PSP(void)
+{
+ __ASM("mrs r0, psp");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM("msr psp, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+uint32_t __get_MSP(void)
+{
+ __ASM("mrs r0, msp");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM("msr msp, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+uint32_t __REV16(uint16_t value)
+{
+ __ASM("rev16 r0, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse bit order of value
+ */
+uint32_t __RBIT(uint32_t value)
+{
+ __ASM("rbit r0, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive (8 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 8 bit values)
+ */
+uint8_t __LDREXB(uint8_t *addr)
+{
+ __ASM("ldrexb r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive (16 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 16 bit values
+ */
+uint16_t __LDREXH(uint16_t *addr)
+{
+ __ASM("ldrexh r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive (32 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 32 bit values
+ */
+uint32_t __LDREXW(uint32_t *addr)
+{
+ __ASM("ldrex r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive (8 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 8 bit values
+ */
+uint32_t __STREXB(uint8_t value, uint8_t *addr)
+{
+ __ASM("strexb r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive (16 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 16 bit values
+ */
+uint32_t __STREXH(uint16_t value, uint16_t *addr)
+{
+ __ASM("strexh r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive (32 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 32 bit values
+ */
+uint32_t __STREXW(uint32_t value, uint32_t *addr)
+{
+ __ASM("strex r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+#pragma diag_default=Pe940
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+uint32_t __get_PSP(void) __attribute__( ( naked ) );
+uint32_t __get_PSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, psp\n\t"
+ "MOV r0, %0 \n\t"
+ "BX lr \n\t" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
+void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n\t"
+ "BX lr \n\t" : : "r" (topOfProcStack) );
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+uint32_t __get_MSP(void) __attribute__( ( naked ) );
+uint32_t __get_MSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, msp\n\t"
+ "MOV r0, %0 \n\t"
+ "BX lr \n\t" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
+void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n\t"
+ "BX lr \n\t" : : "r" (topOfMainStack) );
+}
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @return BasePriority
+ *
+ * Return the content of the base priority register
+ */
+uint32_t __get_BASEPRI(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param basePri BasePriority
+ *
+ * Set the base priority register
+ */
+void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+uint32_t __get_PRIMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @return FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param faultMask faultMask value
+ *
+ * Set the fault mask register
+ */
+void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+/**
+ * @brief Return the Control Register value
+*
+* @return Control value
+ *
+ * Return the content of the control register
+ */
+uint32_t __get_CONTROL(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in integer value
+ */
+uint32_t __REV(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+uint32_t __REV16(uint16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+int32_t __REVSH(int16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse bit order of value
+ */
+uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive (8 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 8 bit value
+ */
+uint8_t __LDREXB(uint8_t *addr)
+{
+ uint8_t result=0;
+
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive (16 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 16 bit values
+ */
+uint16_t __LDREXH(uint16_t *addr)
+{
+ uint16_t result=0;
+
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive (32 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 32 bit values
+ */
+uint32_t __LDREXW(uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive (8 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 8 bit values
+ */
+uint32_t __STREXB(uint8_t value, uint8_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive (16 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 16 bit values
+ */
+uint32_t __STREXH(uint16_t value, uint16_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive (32 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 32 bit values
+ */
+uint32_t __STREXW(uint32_t value, uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
diff --git a/OpenSky/arch/stm32f1/core/core_cm3.h b/OpenSky/arch/stm32f1/core/core_cm3.h
new file mode 100644
index 0000000..783b597
--- /dev/null
+++ b/OpenSky/arch/stm32f1/core/core_cm3.h
@@ -0,0 +1,1818 @@
+/****************************************************************************
+ * @file core_cm3.h
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version V1.30
+ * @date 30. October 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CM3_CORE_H__
+#define __CM3_CORE_H__
+
+/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration
+ *
+ * List of Lint messages which will be suppressed and not shown:
+ * - Error 10: \n
+ * register uint32_t __regBasePri __asm("basepri"); \n
+ * Error 10: Expecting ';'
+ * .
+ * - Error 530: \n
+ * return(__regBasePri); \n
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized
+ * .
+ * - Error 550: \n
+ * __regBasePri = (basePri & 0x1ff); \n
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed
+ * .
+ * - Error 754: \n
+ * uint32_t RESERVED0[24]; \n
+ * Info 754: local structure member '' (line 109, file ./cm3_core.h) not referenced
+ * .
+ * - Error 750: \n
+ * #define __CM3_CORE_H__ \n
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced
+ * .
+ * - Error 528: \n
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced
+ * .
+ * - Error 751: \n
+ * } InterruptType_Type; \n
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced
+ * .
+ * Note: To re-enable a Message, insert a space before 'lint' *
+ *
+ */
+
+/*lint -save */
+/*lint -e10 */
+/*lint -e530 */
+/*lint -e550 */
+/*lint -e754 */
+/*lint -e750 */
+/*lint -e528 */
+/*lint -e751 */
+
+
+/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions
+ This file defines all structures and symbols for CMSIS core:
+ - CMSIS version number
+ - Cortex-M core registers and bitfields
+ - Cortex-M core peripheral base address
+ @{
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03) /*!< Cortex core */
+
+#include /* Include standard types */
+
+#if defined (__ICCARM__)
+ #include /* IAR Intrinsics */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+ #define __I volatile /*!< defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register
+ @{
+*/
+
+
+/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
+ memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
+} NVIC_Type;
+/*@}*/ /* end of group CMSIS_CM3_NVIC */
+
+
+/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB
+ memory mapped structure for System Control Block (SCB)
+ @{
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
+ __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */
+ __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */
+ __IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */
+ __IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */
+ __I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */
+ __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk (0x1FFul << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
+/*@}*/ /* end of group CMSIS_CM3_SCB */
+
+
+/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
+ memory mapped structure for SysTick
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+/*@}*/ /* end of group CMSIS_CM3_SysTick */
+
+
+/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM
+ memory mapped structure for Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */
+ uint32_t RESERVED3[29];
+ __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */
+ __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */
+ __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43];
+ __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */
+ __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */
+ uint32_t RESERVED5[6];
+ __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */
+ __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */
+ __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */
+ __I uint32_t PID7; /*!< Offset: ITM Peripheral Identification Register #7 */
+ __I uint32_t PID0; /*!< Offset: ITM Peripheral Identification Register #0 */
+ __I uint32_t PID1; /*!< Offset: ITM Peripheral Identification Register #1 */
+ __I uint32_t PID2; /*!< Offset: ITM Peripheral Identification Register #2 */
+ __I uint32_t PID3; /*!< Offset: ITM Peripheral Identification Register #3 */
+ __I uint32_t CID0; /*!< Offset: ITM Component Identification Register #0 */
+ __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */
+ __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */
+ __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_ATBID_Pos 16 /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */
+/*@}*/ /* end of group CMSIS_CM3_ITM */
+
+
+/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type
+ memory mapped structure for Interrupt Type
+ @{
+ */
+typedef struct
+{
+ uint32_t RESERVED0;
+ __I uint32_t ICTR; /*!< Offset: 0x04 Interrupt Control Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+ __IO uint32_t ACTLR; /*!< Offset: 0x08 Auxiliary Control Register */
+#else
+ uint32_t RESERVED1;
+#endif
+} InterruptType_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define InterruptType_ICTR_INTLINESNUM_Pos 0 /*!< InterruptType ICTR: INTLINESNUM Position */
+#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define InterruptType_ACTLR_DISFOLD_Pos 2 /*!< InterruptType ACTLR: DISFOLD Position */
+#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos) /*!< InterruptType ACTLR: DISFOLD Mask */
+
+#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 /*!< InterruptType ACTLR: DISDEFWBUF Position */
+#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos) /*!< InterruptType ACTLR: DISDEFWBUF Mask */
+
+#define InterruptType_ACTLR_DISMCYCINT_Pos 0 /*!< InterruptType ACTLR: DISMCYCINT Position */
+#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos) /*!< InterruptType ACTLR: DISMCYCINT Mask */
+/*@}*/ /* end of group CMSIS_CM3_InterruptType */
+
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU
+ memory mapped structure for Memory Protection Unit (MPU)
+ @{
+ */
+typedef struct
+{
+ __I uint32_t TYPE; /*!< Offset: 0x00 MPU Type Register */
+ __IO uint32_t CTRL; /*!< Offset: 0x04 MPU Control Register */
+ __IO uint32_t RNR; /*!< Offset: 0x08 MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< Offset: 0x0C MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< Offset: 0x10 MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< Offset: 0x14 MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< Offset: 0x18 MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< Offset: 0x1C MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: XN Position */
+#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos) /*!< MPU RASR: XN Mask */
+
+#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: AP Position */
+#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos) /*!< MPU RASR: AP Mask */
+
+#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: TEX Position */
+#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos) /*!< MPU RASR: TEX Mask */
+
+#define MPU_RASR_S_Pos 18 /*!< MPU RASR: Shareable bit Position */
+#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos) /*!< MPU RASR: Shareable bit Mask */
+
+#define MPU_RASR_C_Pos 17 /*!< MPU RASR: Cacheable bit Position */
+#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos) /*!< MPU RASR: Cacheable bit Mask */
+
+#define MPU_RASR_B_Pos 16 /*!< MPU RASR: Bufferable bit Position */
+#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos) /*!< MPU RASR: Bufferable bit Mask */
+
+#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENA_Pos 0 /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@}*/ /* end of group CMSIS_CM3_MPU */
+#endif
+
+
+/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug
+ memory mapped structure for Core Debug Register
+ @{
+ */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+/*@}*/ /* end of group CMSIS_CM3_CoreDebug */
+
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
+
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */
+#endif
+
+/*@}*/ /* end of group CMSIS_CM3_core_register */
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#define __enable_fault_irq __enable_fiq
+#define __disable_fault_irq __disable_fiq
+
+#define __NOP __nop
+#define __WFI __wfi
+#define __WFE __wfe
+#define __SEV __sev
+#define __ISB() __isb(0)
+#define __DSB() __dsb(0)
+#define __DMB() __dmb(0)
+#define __REV __rev
+#define __RBIT __rbit
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
+#define __STREXB(value, ptr) __strex(value, ptr)
+#define __STREXH(value, ptr) __strex(value, ptr)
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+
+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */
+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+extern void __CLREX(void);
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @return BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param basePri BasePriority
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @return FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param faultMask faultMask value
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @return Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+#else /* (__ARMCC_VERSION >= 400000) */
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+#define __CLREX __clrex
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @return BasePriority
+ *
+ * Return the content of the base priority register
+ */
+static __INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param basePri BasePriority
+ *
+ * Set the base priority register
+ */
+static __INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xff);
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @return FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+static __INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param faultMask faultMask value
+ *
+ * Set the fault mask register
+ */
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & 1);
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @return Control value
+ *
+ * Return the content of the control register
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+#endif /* __ARMCC_VERSION */
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
+
+static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }
+
+#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */
+static __INLINE void __WFI() { __ASM ("wfi"); }
+static __INLINE void __WFE() { __ASM ("wfe"); }
+static __INLINE void __SEV() { __ASM ("sev"); }
+static __INLINE void __CLREX() { __ASM ("clrex"); }
+
+/* intrinsic void __ISB(void) */
+/* intrinsic void __DSB(void) */
+/* intrinsic void __DMB(void) */
+/* intrinsic void __set_PRIMASK(); */
+/* intrinsic void __get_PRIMASK(); */
+/* intrinsic void __set_FAULTMASK(); */
+/* intrinsic void __get_FAULTMASK(); */
+/* intrinsic uint32_t __REV(uint32_t value); */
+/* intrinsic uint32_t __REVSH(uint32_t value); */
+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */
+/* intrinsic unsigned long __LDREX(unsigned long *); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief LDR Exclusive (8 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 8 bit values)
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief LDR Exclusive (16 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 16 bit values
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief LDR Exclusive (32 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 32 bit values
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief STR Exclusive (8 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 8 bit values
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief STR Exclusive (16 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 16 bit values
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief STR Exclusive (32 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 32 bit values
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }
+static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
+
+static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }
+
+static __INLINE void __NOP() { __ASM volatile ("nop"); }
+static __INLINE void __WFI() { __ASM volatile ("wfi"); }
+static __INLINE void __WFE() { __ASM volatile ("wfe"); }
+static __INLINE void __SEV() { __ASM volatile ("sev"); }
+static __INLINE void __ISB() { __ASM volatile ("isb"); }
+static __INLINE void __DSB() { __ASM volatile ("dsb"); }
+static __INLINE void __DMB() { __ASM volatile ("dmb"); }
+static __INLINE void __CLREX() { __ASM volatile ("clrex"); }
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @return ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param topOfProcStack Process Stack Pointer
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @return Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param topOfMainStack Main Stack Pointer
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @return BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param basePri BasePriority
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @return PriMask
+ *
+ * Return state of the priority mask bit from the priority mask register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param priMask PriMask
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @return FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param faultMask faultMask value
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief Return the Control Register value
+*
+* @return Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param control Control value
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in integer value
+ */
+extern uint32_t __REV(uint32_t value);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param value value to reverse
+ * @return reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief LDR Exclusive (8 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 8 bit value
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief LDR Exclusive (16 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 16 bit values
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief LDR Exclusive (32 bit)
+ *
+ * @param *addr address pointer
+ * @return value of (*address)
+ *
+ * Exclusive LDR command for 32 bit values
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief STR Exclusive (8 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 8 bit values
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief STR Exclusive (16 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 16 bit values
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief STR Exclusive (32 bit)
+ *
+ * @param value value to store
+ * @param *addr address pointer
+ * @return successful / failed
+ *
+ * Exclusive STR command for 32 bit values
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface
+ Core Function Interface containing:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Reset Functions
+*/
+/*@{*/
+
+/* ########################## NVIC functions #################################### */
+
+/**
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller
+ *
+ * @param PriorityGroup is priority grouping field
+ *
+ * Set the priority grouping field using the required unlock sequence.
+ * The parameter priority_grouping is assigned to the field
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */
+ reg_value = (reg_value |
+ (0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8)); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+/**
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller
+ *
+ * @return priority grouping field
+ *
+ * Get the priority grouping from NVIC Interrupt Controller.
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */
+}
+
+/**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn The positive number of the external interrupt to enable
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+/**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn The positive number of the external interrupt to disable
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+/**
+ * @brief Read the interrupt pending bit for a device specific interrupt source
+ *
+ * @param IRQn The number of the device specifc interrupt
+ * @return 1 = interrupt pending, 0 = interrupt not pending
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending,
+ * otherwise it returns 0
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+/**
+ * @brief Set the pending bit for an external interrupt
+ *
+ * @param IRQn The number of the interrupt for set pending
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+/**
+ * @brief Clear the pending bit for an external interrupt
+ *
+ * @param IRQn The number of the interrupt for clear pending
+ *
+ * Clear the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+/**
+ * @brief Read the active bit for an external interrupt
+ *
+ * @param IRQn The number of the interrupt for read active bit
+ * @return 1 = interrupt active, 0 = interrupt not active
+ *
+ * Read the active register in NVIC and returns 1 if its status is active,
+ * otherwise it returns 0.
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+/**
+ * @brief Set the priority for an interrupt
+ *
+ * @param IRQn The number of the interrupt for set priority
+ * @param priority The priority to set
+ *
+ * Set the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if (IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+/**
+ * @brief Read the priority for an interrupt
+ *
+ * @param IRQn The number of the interrupt for get priority
+ * @return The priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if (IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/**
+ * @brief Encode the priority for an interrupt
+ *
+ * @param PriorityGroup The used priority group
+ * @param PreemptPriority The preemptive priority value (starting from 0)
+ * @param SubPriority The sub priority value (starting from 0)
+ * @return The encoded priority for the interrupt
+ *
+ * Encode the priority for an interrupt with the given priority group,
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The returned priority value can be used for NVIC_SetPriority(...) function
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/**
+ * @brief Decode the priority of an interrupt
+ *
+ * @param Priority The priority for the interrupt
+ * @param PriorityGroup The used priority group
+ * @param pPreemptPriority The preemptive priority value (starting from 0)
+ * @param pSubPriority The sub priority value (starting from 0)
+ *
+ * Decode an interrupt priority value with the given priority group to
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The priority value can be retrieved with NVIC_GetPriority(...) function
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+
+/* ################################## SysTick function ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+/**
+ * @brief Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param ticks number of ticks between two interrupts
+ * @return 1 = failed, 0 = successful
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate
+ * periodical interrupts.
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+
+
+
+/* ################################## Reset function ############################################ */
+
+/**
+ * @brief Initiate a system reset request.
+ *
+ * Initiate a system reset request to reset the MCU
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while (1); /* wait until reset */
+}
+
+/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+
+/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface
+ Core Debug Interface containing:
+ - Core Debug Receive / Transmit Functions
+ - Core Debug Defines
+ - Core Debug Variables
+*/
+/*@{*/
+
+extern volatile int ITM_RxBuffer; /*!< variable to receive characters */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */
+
+
+/**
+ * @brief Outputs a character via the ITM channel 0
+ *
+ * @param ch character to output
+ * @return character to output
+ *
+ * The function outputs a character via the ITM channel 0.
+ * The function returns when no debugger is connected that has booked the output.
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */
+ (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
+ (ITM->TER & (1ul << 0) ) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+
+/**
+ * @brief Inputs a character via variable ITM_RxBuffer
+ *
+ * @return received character, -1 = no character received
+ *
+ * The function inputs a character via variable ITM_RxBuffer.
+ * The function returns when no debugger is connected that has booked the output.
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.
+ */
+static __INLINE int ITM_ReceiveChar (void) {
+ int ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ * @brief Check if a character via variable ITM_RxBuffer is available
+ *
+ * @return 1 = character available, 0 = no character available
+ *
+ * The function checks variable ITM_RxBuffer whether a character is available or not.
+ * The function returns '1' if a character is available and '0' if no character is available.
+ */
+static __INLINE int ITM_CheckChar (void) {
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+ return (0); /* no character available */
+ } else {
+ return (1); /* character available */
+ }
+}
+
+/*@}*/ /* end of group CMSIS_CM3_core_DebugInterface */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*@}*/ /* end of group CMSIS_CM3_core_definitions */
+
+#endif /* __CM3_CORE_H__ */
+
+/*lint -restore */
diff --git a/OpenSky/arch/stm32f1/device/startup_stm32f10x.c b/OpenSky/arch/stm32f1/device/startup_stm32f10x.c
new file mode 100644
index 0000000..318c4fa
--- /dev/null
+++ b/OpenSky/arch/stm32f1/device/startup_stm32f10x.c
@@ -0,0 +1,210 @@
+/* Generated by startup_generator */
+
+#include "stm32f10x.h"
+#include
+#include "led.h"
+
+extern void _estack(void); // to force type checking
+void Reset_Handler(void);
+
+void default_handler (void) {
+ uint64_t i;
+ led_red_on();
+ while (1) {
+ for (i=0; i<0x00FFFFF; i++) {}
+ led_green_off();
+ for (i=0; i<0x00FFFFF; i++) {}
+ led_green_on();
+ }
+ while (1);
+}
+
+void __attribute__ ((weak)) __libc_init_array (void) {}
+
+// Linker supplied pointers
+
+extern unsigned long _sidata;
+extern unsigned long _sdata;
+extern unsigned long _edata;
+extern unsigned long _sbss;
+extern unsigned long _ebss;
+
+extern int main(void);
+
+void Reset_Handler(void) {
+
+ unsigned long *src, *dst;
+
+ src = &_sidata;
+ dst = &_sdata;
+
+ // Copy data initializers
+
+ while (dst < &_edata)
+ *(dst++) = *(src++);
+
+ // Zero bss
+
+ dst = &_sbss;
+ while (dst < &_ebss)
+ *(dst++) = 0;
+
+ SystemInit();
+ __libc_init_array();
+ main();
+ while (1) {}
+}
+
+/* Vector Table */
+
+void NMI_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void HardFault_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void MemMange_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void BusFault_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void UsageFault_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void SVC_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void DebugMon_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void PendSV_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void SysTick_Handler (void) __attribute__ ((weak, alias ("default_handler")));
+void WWDG_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void PVD_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TAMPER_STAMP_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void RTC_WKUP_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void FLASH_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void RCC_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI0_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI4_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel4_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel6_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA1_Channel7_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void ADC1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI9_5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM1_BRK_TIM15_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM1_UP_TIM16_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM1_TRG_COM_TIM17_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM1_CC_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM4_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void I2C1_EV_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void I2C1_ER_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void I2C2_EV_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void I2C2_ER_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void SPI1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void SPI2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void USART1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void USART2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void USART3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void EXTI15_10_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void RTCAlarm_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void CEC_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM12_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM13_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM14_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void ADC3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void FSMC_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void SPI3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void UART4_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void UART5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM6_DAC_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void TIM7_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA2_Channel1_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA2_Channel2_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA2_Channel3_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA2_Channel4_5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+void DMA2_Channel5_IRQHandler (void) __attribute__ ((weak, alias ("default_handler")));
+
+
+
+__attribute__ ((section(".isr_vector")))
+
+void (* const g_pfnVectors[])(void) = {
+
+ _estack,
+ Reset_Handler,
+ NMI_Handler,
+ HardFault_Handler,
+ MemMange_Handler,
+ BusFault_Handler,
+ UsageFault_Handler,
+ 0, 0, 0, 0,
+ SVC_Handler,
+ DebugMon_Handler,
+ 0,
+ PendSV_Handler,
+ SysTick_Handler,
+ WWDG_IRQHandler,
+ PVD_IRQHandler,
+ TAMPER_STAMP_IRQHandler,
+ RTC_WKUP_IRQHandler,
+ FLASH_IRQHandler,
+ RCC_IRQHandler,
+ EXTI0_IRQHandler,
+ EXTI1_IRQHandler,
+ EXTI2_IRQHandler,
+ EXTI3_IRQHandler,
+ EXTI4_IRQHandler,
+ DMA1_Channel1_IRQHandler,
+ DMA1_Channel2_IRQHandler,
+ DMA1_Channel3_IRQHandler,
+ DMA1_Channel4_IRQHandler,
+ DMA1_Channel5_IRQHandler,
+ DMA1_Channel6_IRQHandler,
+ DMA1_Channel7_IRQHandler,
+ ADC1_IRQHandler,
+ 0, 0, 0, 0,
+ EXTI9_5_IRQHandler,
+ TIM1_BRK_TIM15_IRQHandler,
+ TIM1_UP_TIM16_IRQHandler,
+ TIM1_TRG_COM_TIM17_IRQHandler,
+ TIM1_CC_IRQHandler,
+ TIM2_IRQHandler,
+ TIM3_IRQHandler,
+ TIM4_IRQHandler,
+ I2C1_EV_IRQHandler,
+ I2C1_ER_IRQHandler,
+ I2C2_EV_IRQHandler,
+ I2C2_ER_IRQHandler,
+ SPI1_IRQHandler,
+ SPI2_IRQHandler,
+ USART1_IRQHandler,
+ USART2_IRQHandler,
+ USART3_IRQHandler,
+ EXTI15_10_IRQHandler,
+ RTCAlarm_IRQHandler,
+ CEC_IRQHandler,
+ TIM12_IRQHandler,
+ TIM13_IRQHandler,
+ TIM14_IRQHandler,
+ 0,
+ ADC3_IRQHandler,
+ FSMC_IRQHandler,
+ 0,
+ TIM5_IRQHandler,
+ SPI3_IRQHandler,
+ UART4_IRQHandler,
+ UART5_IRQHandler,
+ TIM6_DAC_IRQHandler,
+ TIM7_IRQHandler,
+ DMA2_Channel1_IRQHandler,
+ DMA2_Channel2_IRQHandler,
+ DMA2_Channel3_IRQHandler,
+ DMA2_Channel4_5_IRQHandler,
+ DMA2_Channel5_IRQHandler,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL)
+ [0x1CC/4] = 0xF108F85F
+#elif defined (STM32F10X_HD_VL)
+ [0x1E0/4] = 0xF108F85F
+#endif
+
+ };
diff --git a/OpenSky/arch/stm32f1/device/stm32f10x.h b/OpenSky/arch/stm32f1/device/stm32f10x.h
new file mode 100644
index 0000000..af0c7c9
--- /dev/null
+++ b/OpenSky/arch/stm32f1/device/stm32f10x.h
@@ -0,0 +1,8336 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x.h
+ * @author MCD Application Team
+ * @version V3.5.0
+ * @date 11-March-2011
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
+ * This file contains all the peripheral register's definitions, bits
+ * definitions and memory mapping for STM32F10x Connectivity line,
+ * High density, High density value line, Medium density,
+ * Medium density Value line, Low density, Low density Value line
+ * and XL-density devices.
+ *
+ * The file is the unique include file that the application programmer
+ * is using in the C source code, usually in main.c. This file contains:
+ * - Configuration section that allows to select:
+ * - The device used in the target application
+ * - To use or not the peripherals drivers in application code(i.e.
+ * code will be based on direct access to peripherals registers
+ * rather than drivers API), this option is controlled by
+ * "#define USE_STDPERIPH_DRIVER"
+ * - To change few application-specific parameters such as the HSE
+ * crystal frequency
+ * - Data structures and the address mapping for all peripherals
+ * - Peripheral's registers declarations and bits definition
+ * - Macros to access peripherals registers hardware
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f10x_system
+ * @{
+ */
+
+/**
+ * @brief Define to prevent recursive inclusion
+ */
+#ifndef __SYSTEM_STM32F10X_H
+#define __SYSTEM_STM32F10X_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup STM32F10x_System_Includes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32F10x_System_Exported_types
+ * @{
+ */
+
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Functions
+ * @{
+ */
+
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SYSTEM_STM32F10X_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/OpenSky/arch/stm32f1/hal_adc.c b/OpenSky/arch/stm32f1/hal_adc.c
new file mode 100644
index 0000000..b695fd7
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_adc.c
@@ -0,0 +1,185 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_adc.h"
+#include "debug.h"
+#include "wdt.h"
+#include "config.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_dma.h"
+#include "stm32f10x_adc.h"
+
+// adc results
+volatile uint16_t hal_adc_data[2];
+
+void hal_adc_init(void) {
+ hal_adc_init_rcc();
+ hal_adc_init_gpio();
+ hal_adc_init_mode();
+ hal_adc_init_dma();
+}
+
+static void hal_adc_init_rcc(void) {
+ // ADC CLOCK = 24 / 4 = 6MHz
+ RCC_ADCCLKConfig(RCC_PCLK2_Div4);
+
+ // enable ADC clock
+ RCC_APBxPeriphClockCmd(ADC_CLK_RCC, ADC_CLK, ENABLE);
+
+ // enable dma clock
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
+
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(ADC_GPIO_CLK_RCC, ADC_GPIO_CLK, ENABLE);
+}
+
+static void hal_adc_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // set up analog inputs
+ gpio_init.GPIO_Pin = ADC_IN1_PIN | ADC_IN2_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_AIN;
+ GPIO_Init(ADC_GPIO, &gpio_init);
+}
+
+static void hal_adc_init_mode(void) {
+ ADC_InitTypeDef adc_init;
+
+ // ADC configuration
+ adc_init.ADC_Mode = ADC_Mode_Independent;
+ // convert multiple channels
+ adc_init.ADC_ScanConvMode = ENABLE;
+ // select continuous conversion mode
+ adc_init.ADC_ContinuousConvMode = ENABLE;
+ // select no external triggering
+ adc_init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
+ // right 12-bit data alignment in ADC data register
+ adc_init.ADC_DataAlign = ADC_DataAlign_Right;
+ // 2 channels conversion
+ adc_init.ADC_NbrOfChannel = 2;
+
+ // load structure values to control and status registers
+ ADC_Init(ADC, &adc_init);
+
+ // configure each channel
+ ADC_RegularChannelConfig(ADC, ADC_Channel_1, 1, ADC_SampleTime_41Cycles5);
+ ADC_RegularChannelConfig(ADC, ADC_Channel_2, 2, ADC_SampleTime_41Cycles5);
+
+ // Enable ADC
+ ADC_Cmd(ADC, ENABLE);
+
+ // enable DMA for ADC
+ ADC_DMACmd(ADC, ENABLE);
+
+ // Enable ADC1 reset calibration register
+ ADC_ResetCalibration(ADC);
+
+ // Check the end of ADC1 reset calibration register
+ while (ADC_GetResetCalibrationStatus(ADC)) {}
+
+ // Start ADC calibration
+ ADC_StartCalibration(ADC);
+
+ // Check the end of ADC1 calibration
+ while (ADC_GetCalibrationStatus(ADC)) {}
+}
+
+static void hal_adc_init_dma(void) {
+ DMA_InitTypeDef dma_init;
+
+ // reset DMA1 channe1 to default values
+ DMA_DeInit(ADC_DMA_CHANNEL);
+
+ // set up dma to convert 2 adc channels to two mem locations:
+ // channel will be used for memory to memory transfer
+ dma_init.DMA_M2M = DMA_M2M_Disable;
+ // setting normal mode (non circular)
+ dma_init.DMA_Mode = DMA_Mode_Circular;
+ // medium priority
+ dma_init.DMA_Priority = DMA_Priority_High;
+ // source and destination 16bit
+ dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+ dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+ // automatic memory destination increment enable.
+ dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ // source address increment disable
+ dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ // Location assigned to peripheral register will be source
+ dma_init.DMA_DIR = DMA_DIR_PeripheralSRC;
+ // chunk of data to be transfered
+ dma_init.DMA_BufferSize = 2;
+ // source and destination start addresses
+ dma_init.DMA_PeripheralBaseAddr = (uint32_t)&ADC->DR;
+ dma_init.DMA_MemoryBaseAddr = (uint32_t)hal_adc_data;
+ // send values to DMA registers
+ DMA_Init(ADC_DMA_CHANNEL, &dma_init);
+
+ // Enable the DMA1 - Channel1
+ DMA_Cmd(ADC_DMA_CHANNEL, ENABLE);
+
+ // start conversion:
+ hal_adc_dma_arm();
+
+#if ADC_DO_TEST
+ // TEST ADC
+ while (1) {
+ debug_putc('A');
+ wdt_reset();
+ if (ADC_GetFlagStatus(ADC, ADC_FLAG_EOC) == SET) {
+ uint16_t res = ADC_GetConversionValue(ADC);
+ debug("ADC = "); debug_put_uint16(res); debug_put_newline(); debug_flush();
+
+ ADC_ClearFlag(ADC, ADC_FLAG_EOC);
+ // start next ADC Software Conversion
+ ADC_SoftwareStartConvCmd(ADC, ENABLE);
+ }
+ }
+#endif // ADC_DO_TEST
+}
+
+static void hal_adc_dma_arm(void) {
+ ADC_SoftwareStartConvCmd(ADC, ENABLE);
+}
+
+void hal_adc_process(void) {
+ // adc dma finished?
+ if (DMA_GetITStatus(ADC_DMA_TC_FLAG)) {
+ // fine, arm DMA again:
+ hal_adc_dma_arm();
+ } else {
+ // oops this should not happen
+ debug_putc('D');
+ // cancel and re arm dma ???
+ }
+}
+
+uint8_t hal_adc_get_scaled(uint8_t ch) {
+ if (ch < 2) {
+ // 12 bit adc -> scale to 8 bit -> shift by 4
+ return hal_adc_data[ch]>>4;
+ } else {
+ debug("hal_adc: channel index out of bounds ");
+ debug_put_uint8(ch);
+ debug("allowed 0,1)\n");
+ debug_flush();
+ return 0;
+ }
+}
+
diff --git a/OpenSky/arch/stm32f1/hal_adc.h b/OpenSky/arch/stm32f1/hal_adc.h
new file mode 100644
index 0000000..c9e32a9
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_adc.h
@@ -0,0 +1,39 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_ADC_H_
+#define HAL_ADC_H_
+
+#include "main.h"
+#include
+
+extern volatile uint16_t hal_adc_data[2];
+
+void hal_adc_init(void);
+
+static void hal_adc_init_rcc(void);
+static void hal_adc_init_gpio(void);
+static void hal_adc_init_mode(void);
+static void hal_adc_init_dma(void);
+static void hal_adc_dma_arm(void);
+
+uint8_t hal_adc_get_scaled(uint8_t ch);
+void hal_adc_process(void);
+
+#endif // HAL_ADC_H_
diff --git a/OpenSky/arch/stm32f1/hal_cc25xx.c b/OpenSky/arch/stm32f1/hal_cc25xx.c
new file mode 100644
index 0000000..ab3c24b
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_cc25xx.c
@@ -0,0 +1,289 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_cc25xx.h"
+#include "hal_spi.h"
+#include "cc25xx.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_rcc.h"
+#include "debug.h"
+#include "timeout.h"
+#include
+
+void hal_cc25xx_init(void) {
+ hal_spi_init();
+ hal_cc25xx_init_gpio();
+}
+
+static void hal_cc25xx_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // antenna switch
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(CC25XX_ANT_SW_CTX_GPIO_CLK_RCC, CC25XX_ANT_SW_CTX_GPIO_CLK, ENABLE);
+ RCC_APBxPeriphClockCmd(CC25XX_ANT_SW_CRX_GPIO_CLK_RCC, CC25XX_ANT_SW_CRX_GPIO_CLK, ENABLE);
+
+ // CTX:
+ gpio_init.GPIO_Pin = CC25XX_ANT_SW_CTX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(CC25XX_ANT_SW_CTX_GPIO, &gpio_init);
+ // CRX:
+ gpio_init.GPIO_Pin = CC25XX_ANT_SW_CRX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(CC25XX_ANT_SW_CRX_GPIO, &gpio_init);
+
+ // select first antenna
+ hal_cc25xx_set_antenna(0);
+
+ // PA/LNA:
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(CC25XX_LNA_SW_CTX_GPIO_CLK_RCC, CC25XX_LNA_SW_CTX_GPIO_CLK, ENABLE);
+ RCC_APBxPeriphClockCmd(CC25XX_LNA_SW_CRX_GPIO_CLK_RCC, CC25XX_LNA_SW_CRX_GPIO_CLK, ENABLE);
+
+
+ // CTX:
+ gpio_init.GPIO_Pin = CC25XX_LNA_SW_CTX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(CC25XX_LNA_SW_CTX_GPIO, &gpio_init);
+ // CRX:
+ gpio_init.GPIO_Pin = CC25XX_LNA_SW_CRX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(CC25XX_LNA_SW_CRX_GPIO, &gpio_init);
+ hal_cc25xx_enter_rxmode();
+
+ // JTAG IS ON LNA pins! -> DISABLE JTAG!
+ RCC_APBxPeriphClockCmd(2, RCC_APB2Periph_AFIO, ENABLE);
+ GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
+
+ // GDO2
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(CC25XX_GDO2_GPIO_CLK_RCC, CC25XX_GDO2_GPIO_CLK, ENABLE);
+
+ // configure GDO2 pin as Input floating
+ gpio_init.GPIO_Pin = CC25XX_GDO2_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init(CC25XX_GDO2_GPIO, &gpio_init);
+}
+
+inline uint32_t hal_cc25xx_set_antenna(uint8_t id) {
+ // select antenna 0 or 1:
+ if (id) {
+ CC25XX_ANT_SW_CTX_GPIO->BRR = (CC25XX_ANT_SW_CTX_PIN); // 0
+ CC25XX_ANT_SW_CRX_GPIO->BSRR = (CC25XX_ANT_SW_CRX_PIN); // 1
+ } else {
+ CC25XX_ANT_SW_CTX_GPIO->BSRR = (CC25XX_ANT_SW_CTX_PIN); // 1
+ CC25XX_ANT_SW_CRX_GPIO->BRR = (CC25XX_ANT_SW_CRX_PIN); // 0
+ }
+ return id;
+}
+
+inline void hal_cc25xx_set_gdo_mode(void) {
+ cc25xx_set_register(IOCFG0, 0x01); // 6);
+ // cc25xx_set_register(IOCFG1, ???);
+ cc25xx_set_register(IOCFG2, 0x01); // 6);
+}
+
+inline void hal_cc25xx_set_register(uint8_t address, uint8_t data) {
+ // select device
+ hal_spi_csn_lo();
+
+ // wait for ready signal
+ while (GPIO_ReadInputDataBit(CC25XX_SPI_GPIO, CC25XX_SPI_MISO_PIN) == 1) {}
+
+ hal_spi_tx(address);
+ hal_spi_tx(data);
+
+ // deslect
+ hal_spi_csn_hi();
+}
+
+inline uint8_t hal_cc25xx_get_register(uint8_t address) {
+ uint8_t result;
+
+ // select device:
+ hal_spi_csn_lo();
+
+ // wait for RDY signal:
+ while (GPIO_ReadInputDataBit(CC25XX_SPI_GPIO, CC25XX_SPI_MISO_PIN) == 1) {}
+
+ // request address (read request has bit7 set)
+ uint8_t status = hal_spi_tx(address | 0x80);
+ // debug_put_hex8(status);
+
+ // fetch result:
+ result = hal_spi_rx();
+
+ // deselect device
+ hal_spi_csn_hi();
+
+ // return result
+ return(result);
+}
+
+inline void hal_cc25xx_strobe(uint8_t address) {
+ hal_spi_csn_lo();
+ uint8_t status = hal_spi_tx(address);
+ // debug("s"); debug_put_hex8(status); debug_put_newline();
+ hal_spi_csn_hi();
+}
+
+inline uint8_t hal_cc25xx_get_status(void) {
+ hal_spi_csn_lo();
+ uint8_t status = hal_spi_tx(0xFF);
+ hal_spi_csn_hi();
+ return status;
+}
+
+uint8_t hal_cc25xx_transmission_completed(void) {
+ // after tx cc25xx goes back to RX (configured by mcsm1 register)
+ return ((hal_cc25xx_get_status() & (0x70)) == CC2500_STATUS_STATE_RX);
+}
+
+inline void hal_cc25xx_enter_rxmode(void) {
+ // add pa/lna config bit setting here
+ CC25XX_LNA_SW_CRX_GPIO->BSRR = (CC25XX_LNA_SW_CRX_PIN); // 1
+ delay_us(20);
+ CC25XX_LNA_SW_CTX_GPIO->BRR = (CC25XX_LNA_SW_CTX_PIN); // 0
+ delay_us(5);
+}
+
+inline void hal_cc25xx_enter_txmode(void) {
+ // add pa/lna config bit setting here
+ CC25XX_LNA_SW_CRX_GPIO->BRR = (CC25XX_LNA_SW_CRX_PIN); // 0
+ delay_us(20);
+ CC25XX_LNA_SW_CTX_GPIO->BSRR = (CC25XX_LNA_SW_CTX_PIN); // 1
+ delay_us(5);
+}
+
+
+inline void hal_cc25xx_enable_receive(void) {
+ // switch on rx again
+ hal_cc25xx_enter_rxmode();
+}
+
+
+inline uint8_t hal_cc25xx_get_gdo_status(void) {
+ if (GPIO_ReadInputDataBit(CC25XX_GDO2_GPIO, GPIO_Pin_3)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+inline void hal_cc25xx_read_fifo(uint8_t *buf, uint8_t len) {
+ hal_cc25xx_register_read_multi(CC25XX_FIFO | READ_FLAG | BURST_FLAG, buf, len);
+}
+
+inline void hal_cc25xx_register_read_multi(uint8_t address, uint8_t *buffer, uint8_t len) {
+ // select device:
+ hal_spi_csn_lo();
+
+ // wait for ready signal
+ while (GPIO_ReadInputDataBit(CC25XX_SPI_GPIO, CC25XX_SPI_MISO_PIN) == 1) {}
+
+ // debug("read "); debug_put_uint8(len); debug_flush();
+ // request address (read request)
+ uint8_t status = hal_spi_tx(address);
+
+ // fill buffer with read commands:
+ memset(buffer, 0xFF, len);
+
+ hal_spi_dma_xfer(buffer, len);
+ /*
+ while (len--) {
+ *buf = hal_spi_rx();
+ buf++;
+ }*/
+
+ // deselect device
+ hal_spi_csn_hi();
+}
+
+inline void hal_cc25xx_register_write_multi(uint8_t address, uint8_t *buffer, uint8_t len) {
+ // s elect device:
+ hal_spi_csn_lo();
+
+ // wait for RDY signal:
+ while (GPIO_ReadInputDataBit(CC25XX_SPI_GPIO, CC25XX_SPI_MISO_PIN) == 1) {}
+
+ // request address (write request)
+ hal_spi_tx(address | BURST_FLAG);
+
+ // send array
+ hal_spi_dma_xfer(buffer, len);
+
+ // deselect device
+ hal_spi_csn_hi();
+}
+
+inline void hal_cc25xx_process_packet(volatile uint8_t *packet_received,
+ volatile uint8_t *buffer, uint8_t maxlen) {
+ if (hal_cc25xx_get_gdo_status() == 1) {
+ // data received, fetch data
+ // timeout_set_100us(5);
+
+ *packet_received = 0;
+
+ // there is a bug in the cc2500
+ // see p3 http:// www.ti.com/lit/er/swrz002e/swrz002e.pdf
+ // workaround: read len register very quickly twice:
+ uint8_t len1, len2, len, i;
+
+ // try this 10 times befor giving up:
+ for (i = 0; i < 10; i++) {
+ len1 = hal_cc25xx_get_register_burst(RXBYTES) & 0x7F;
+ len2 = hal_cc25xx_get_register_burst(RXBYTES) & 0x7F;
+ if (len1 == len2) break;
+ }
+
+ // valid len found?
+ if (len1 == len2) {
+ len = len1;
+
+ // packet received, grab data
+ uint8_t tmp_buffer[len];
+ hal_cc25xx_read_fifo(tmp_buffer, len);
+
+ // only accept valid packet lenbghts:
+ if (len == maxlen) {
+ uint8_t i;
+ for (i = 0; i < maxlen; i++) {
+ buffer[i] = tmp_buffer[i];
+ }
+ *packet_received = 1;
+ }
+ } else {
+ // no, ignore this
+ len = 0;
+ }
+ }
+}
+
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len) {
+ // flush tx fifo
+ hal_cc25xx_strobe(RFST_SFTX);
+ // copy to fifo
+ hal_cc25xx_register_write_multi(CC25XX_FIFO, (uint8_t *)buffer, buffer[0]+1);
+ // and send!
+ hal_cc25xx_strobe(RFST_STX);
+}
diff --git a/OpenSky/arch/stm32f1/hal_cc25xx.h b/OpenSky/arch/stm32f1/hal_cc25xx.h
new file mode 100644
index 0000000..56129e0
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_cc25xx.h
@@ -0,0 +1,186 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_CC25XX_H__
+#define HAL_CC25XX_H__
+
+#include
+
+void hal_cc25xx_init(void);
+void hal_cc25xx_set_register(uint8_t reg, uint8_t val);
+uint8_t hal_cc25xx_get_register(uint8_t address);
+void hal_cc25xx_strobe(uint8_t val);
+
+void hal_cc25xx_enable_receive(void);
+void hal_cc25xx_enable_transmit(void);
+void hal_cc25xx_enter_rxmode(void);
+void hal_cc25xx_enter_txmode(void);
+
+#define hal_cc25xx_rx_sleep() { delay_us(1352); }
+#define hal_cc25xx_tx_sleep() { delay_us(1250); }
+
+// not used on d4rii
+#define hal_cc25xx_disable_rf_interrupt() {}
+#define hal_cc25xx_setup_rf_dma(mode) {}
+#define hal_cc25xx_partnum_valid(p, v) ((p == 0x80) && (v = 0x03))
+
+uint8_t hal_cc25xx_get_status(void);
+static void hal_cc25xx_init_gpio(void);
+uint32_t hal_cc25xx_set_antenna(uint8_t id);
+void hal_cc25xx_set_gdo_mode(void);
+uint8_t hal_cc25xx_get_gdo_status(void);
+void hal_cc25xx_process_packet(volatile uint8_t *packet_received,
+ volatile uint8_t *buffer, uint8_t maxlen);
+void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len);
+
+void hal_cc25xx_read_fifo(uint8_t *buf, uint8_t len);
+void hal_cc25xx_register_read_multi(uint8_t address, uint8_t *buffer, uint8_t len);
+uint8_t hal_cc25xx_transmission_completed(void);
+
+// adress checks
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_00 ((0<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_01 ((0<<1) | (1<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_10 ((1<<1) | (0<<0))
+#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_11 ((1<<1) | (1<<0))
+// append status bytes?
+#define CC2500_PKTCTRL1_APPEND_STATUS (1<<2)
+// crc autoflush
+#define CC2500_PKTCTRL1_CRC_AUTOFLUSH (1<<3)
+
+// Flags
+#define BURST_FLAG 0b01000000
+#define WRITE_FLAG 0b00000000
+#define READ_FLAG 0b10000000
+
+// Definitions for burst/single access to registers
+#define CC2500_WRITE_SINGLE 0x00
+#define CC2500_WRITE_BURST 0x40
+#define CC2500_READ_SINGLE 0x80
+#define CC2500_READ_BURST 0xC0
+
+#define CC2500_STATUS_STATE_IDLE (0<<4)
+#define CC2500_STATUS_STATE_RX (1<<4)
+#define CC2500_STATUS_STATE_TX (2<<4)
+#define CC2500_STATUS_STATE_FSTXON (3<<4)
+#define CC2500_STATUS_STATE_CALIBRATE (4<<4)
+#define CC2500_STATUS_STATE_SETTLING (5<<4)
+#define CC2500_STATUS_STATE_RXFIFO_OVF (6<<4)
+#define CC2500_STATUS_STATE_TXFIFO_OVF (7<<4)
+
+#define hal_cc25xx_get_register_burst(x) hal_cc25xx_get_register(x | READ_FLAG | BURST_FLAG)
+
+
+// strobes
+#define RFST_SRES 0x30
+#define RFST_SFSTXON 0x31
+#define RFST_SXOFF 0x32
+#define RFST_SCAL 0x33
+#define RFST_SRX 0x34
+#define RFST_STX 0x35
+#define RFST_SIDLE 0x36
+#define RFST_SWOR 0x38
+#define RFST_SPWD 0x39
+#define RFST_SFRX 0x3A
+#define RFST_SFTX 0x3B
+#define RFST_SWORRST 0x3C
+#define RFST_SNOP 0x3D
+
+// Status registers
+#define PARTNUM 0x30|BURST_FLAG
+#define VERSION 0x31|BURST_FLAG
+#define FREQEST 0x32|BURST_FLAG
+#define LQI 0x33|BURST_FLAG
+#define RSSI 0x34|BURST_FLAG
+#define MARCSTATE 0x35|BURST_FLAG
+#define WORTIME1 0x36|BURST_FLAG
+#define WORTIME0 0x37|BURST_FLAG
+#define PKTSTATUS 0x38|BURST_FLAG
+#define VCO_VC_DAC 0x39|BURST_FLAG
+#define TXBYTES 0x3A|BURST_FLAG
+#define RXBYTES 0x3B|BURST_FLAG
+#define RCCTRL1_STATUS 0x3C|BURST_FLAG
+#define RCCTRL0_STATUS 0x3D|BURST_FLAG
+
+// Status byte states
+#define STB_IDLE 0x00
+#define STB_RX 0x10
+#define STB_TX 0x20
+#define STB_FSTXON 0x30
+#define STB_CALIBRATE 0x40
+#define STB_SETTLING 0x50
+#define STB_RX_OVF 0x60
+#define STB_TX_UNDF 0x70
+
+// Config registers addresses
+#define IOCFG2 0x00
+#define IOCFG1 0x01
+#define IOCFG0 0x02
+#define FIFOTHR 0x03
+#define SYNC1 0x04
+#define SYNC0 0x05
+#define PKTLEN 0x06
+#define PKTCTRL1 0x07
+#define PKTCTRL0 0x08
+#define ADDR 0x09
+#define CHANNR 0x0A
+#define FSCTRL1 0x0B
+#define FSCTRL0 0x0C
+#define FREQ2 0x0D
+#define FREQ1 0x0E
+#define FREQ0 0x0F
+#define MDMCFG4 0x10
+#define MDMCFG3 0x11
+#define MDMCFG2 0x12
+#define MDMCFG1 0x13
+#define MDMCFG0 0x14
+#define DEVIATN 0x15
+#define MCSM2 0x16
+#define MCSM1 0x17
+#define MCSM0 0x18
+#define FOCCFG 0x19
+#define BSCFG 0x1A
+#define AGCCTRL2 0x1B
+#define AGCCTRL1 0x1C
+#define AGCCTRL0 0x1D
+#define WOREVT1 0x1E
+#define WOREVT0 0x1F
+#define WORCTRL 0x20
+#define FREND1 0x21
+#define FREND0 0x22
+#define FSCAL3 0x23
+#define FSCAL2 0x24
+#define FSCAL1 0x25
+#define FSCAL0 0x26
+#define RCCTRL1 0x27
+#define RCCTRL0 0x28
+#define FSTEST 0x29
+#define PTEST 0x2A
+#define AGCTEST 0x2B
+#define TEST2 0x2C
+#define TEST1 0x2D
+#define TEST0 0x2E
+
+#define PA_TABLE0 0x3E
+
+// FIFO
+#define CC25XX_FIFO 0x3F
+
+
+#endif // HAL_CC25XX_H_
+
diff --git a/OpenSky/arch/stm32f1/hal_clocksource.c b/OpenSky/arch/stm32f1/hal_clocksource.c
new file mode 100644
index 0000000..9390664
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_clocksource.c
@@ -0,0 +1,22 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_clocksource.h"
+
+// nothing to do here
diff --git a/OpenSky/arch/stm32f1/hal_clocksource.h b/OpenSky/arch/stm32f1/hal_clocksource.h
new file mode 100644
index 0000000..28c0367
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_clocksource.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_CLOCKSOURCE_H_
+#define HAL_CLOCKSOURCE_H_
+
+// not necessary for stm32, it is done in system startup
+#define hal_clocksource_init() {}
+
+#endif // HAL_CLOCKSOURCE_H_
diff --git a/OpenSky/arch/stm32f1/hal_debug.c b/OpenSky/arch/stm32f1/hal_debug.c
new file mode 100644
index 0000000..1043c19
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_debug.c
@@ -0,0 +1,108 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_uart.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_usart.h"
+#include "misc.h" // this is actually a stm32 include (nvic stuff)
+#include "debug.h"
+#include "led.h"
+
+volatile uint8_t hal_debug_txe_is_on;
+
+void hal_debug_init(void) {
+ hal_debug_txe_is_on = 0;
+
+ hal_debug_init_nvic(0);
+ hal_debug_init_rcc();
+ hal_debug_init_gpio();
+ hal_debug_init_mode();
+ hal_debug_enable();
+}
+
+void hal_debug_init_nvic(uint8_t enable) {
+ // enable interrupts
+ NVIC_InitTypeDef nvic_init;
+
+
+ // configure the NVIC Preemption Priority Bits
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
+
+ // enable the USART interrupt
+ nvic_init.NVIC_IRQChannel = DEBUG_USART_IRQn;
+ nvic_init.NVIC_IRQChannelPreemptionPriority = NVIC_PRIO_DEBUG_UART;
+ nvic_init.NVIC_IRQChannelSubPriority = 0;
+ nvic_init.NVIC_IRQChannelCmd = enable ? ENABLE : DISABLE;
+ NVIC_Init(&nvic_init);
+}
+
+
+static void hal_debug_init_mode(void) {
+ USART_InitTypeDef uart_init;
+
+ // USART configuration:
+ // 115200 baud, 8N1
+ // no hw flow control
+ uart_init.USART_BaudRate = 115200;
+ uart_init.USART_WordLength = USART_WordLength_8b;
+ uart_init.USART_StopBits = USART_StopBits_1;
+ uart_init.USART_Parity = USART_Parity_No;
+ uart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ uart_init.USART_Mode = USART_Mode_Tx;
+ USART_Init(DEBUG_USART, &uart_init);
+}
+
+static void hal_debug_enable(void) {
+ // enable uart
+ USART_Cmd(DEBUG_USART, ENABLE);
+}
+
+void hal_debug_start_transmission(uint8_t ch) {
+ // enable TXE int
+ USART_ITConfig(DEBUG_USART, USART_IT_TXE, ENABLE);
+ hal_debug_txe_is_on = 1;
+
+ // send first byte
+ USART_SendData(DEBUG_USART, ch);
+}
+
+uint8_t hal_debug_int_enabled(void) {
+ // is the txe int enabled?
+ return hal_debug_txe_is_on;
+}
+
+static void hal_debug_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // Configure USART TX as alternate function push-pull
+ gpio_init.GPIO_Pin = DEBUG_USART_TX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(DEBUG_USART_GPIO, &gpio_init);
+}
+
+static void hal_debug_init_rcc(void) {
+ // configure clocks for uart:
+ // enable GPIO clock
+ RCC_APBxPeriphClockCmd(DEBUG_USART_GPIO_CLK_RCC,
+ DEBUG_USART_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
+
+ // enable USART clock
+ RCC_APBxPeriphClockCmd(DEBUG_USART_CLK_RCC, DEBUG_USART_CLK, ENABLE);
+}
diff --git a/OpenSky/arch/stm32f1/hal_debug.h b/OpenSky/arch/stm32f1/hal_debug.h
new file mode 100644
index 0000000..59ac2b2
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_debug.h
@@ -0,0 +1,53 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DEBUG_H_
+#define HAL_DEBUG_H_
+
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_usart.h"
+#include "config.h"
+#include "hal_uart.h"
+
+extern volatile uint8_t hal_debug_txe_is_on;
+
+void hal_debug_init(void);
+void hal_debug_start_transmission(uint8_t ch);
+
+#define hal_debug_int_enable() { hal_debug_init_nvic(1); }
+#define hal_debug_int_disable() { hal_debug_init_nvic(0); }
+
+uint8_t hal_debug_int_enabled(void);
+
+void hal_debug_init_nvic(uint8_t enable);
+static void hal_debug_init_rcc(void);
+static void hal_debug_init_gpio(void);
+static void hal_debug_init_mode(void);
+static void hal_debug_enable(void);
+
+#define DEBUG_ISR(void) DEBUG_USART_IRQHANDLER(void)
+#define HAL_DEBUG_ISR_FLAG_SET() (USART_GetITStatus(DEBUG_USART, USART_IT_TXE) != RESET)
+#define HAL_DEBUG_ISR_CLEAR_FLAG() { }
+#define HAL_DEBUG_ISR_DISABLE() {\
+ USART_ITConfig(DEBUG_USART, USART_IT_TXE, DISABLE); hal_debug_txe_is_on = 0; }
+#define HAL_DEBUG_TX_DATA(data) {\
+ USART_SendData(DEBUG_USART, data); }
+
+
+#endif // HAL_DEBUG_H_
diff --git a/OpenSky/arch/stm32f1/hal_defines.h b/OpenSky/arch/stm32f1/hal_defines.h
new file mode 100644
index 0000000..98db2d5
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_defines.h
@@ -0,0 +1,16 @@
+#ifndef __HAL_DEFINES_H__
+#define __HAL_DEFINES_H__
+
+#include "stm32f10x_rcc.h"
+
+#define EXTERNAL_MEMORY
+#define EXTERNAL_DATA
+
+// auto selector for APB1/APB2:
+#define RCC_APBxPeriphClockCmd(rcc, p, s) { if (rcc == 1) { RCC_APB1PeriphClockCmd(p,s); } else { RCC_APB2PeriphClockCmd(p, s); } }
+#define RCC_APBxPeriphResetCmd(rcc, p, s) { if (rcc == 1) { RCC_APB1PeriphResetCmd(p,s); } else { RCC_APB2PeriphResetCmd(p, s); } }
+
+#define LO(w) (w & 0xFF)
+#define HI(w) ((w>>8) & 0xFF)
+
+#endif // __HAL_DEFINES_H__
diff --git a/OpenSky/arch/stm32f1/hal_delay.c b/OpenSky/arch/stm32f1/hal_delay.c
new file mode 100644
index 0000000..27ec70e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_delay.c
@@ -0,0 +1,36 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_delay.h"
+
+inline void hal_delay_us(uint32_t us) {
+ // based on https:// github.com/leaflabs/libmaple
+ us *= 8;
+
+ // fudge for function call overhead
+ us--;
+ us--;
+ us--;
+ asm volatile(" mov r0, %[us] \n\t"
+ "1: subs r0, #1 \n\t"
+ " bhi 1b \n\t"
+ :
+ : [us] "r" (us)
+ : "r0");
+}
diff --git a/OpenSky/arch/stm32f1/hal_delay.h b/OpenSky/arch/stm32f1/hal_delay.h
new file mode 100644
index 0000000..e2b5c46
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_delay.h
@@ -0,0 +1,29 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_DELAY_H_
+#define HAL_DELAY_H_
+
+#include "hal_timeout.h"
+
+#define hal_delay_ms(ms) hal_timeout_delay_ms(ms)
+void hal_delay_us(uint32_t us);
+
+
+#endif // HAL_DELAY_H_
diff --git a/OpenSky/arch/stm32f1/hal_dma.c b/OpenSky/arch/stm32f1/hal_dma.c
new file mode 100644
index 0000000..d2c5115
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_dma.c
@@ -0,0 +1,20 @@
+/*
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_dma.h"
+
+// nothing to do here...
diff --git a/OpenSky/arch/stm32f1/hal_dma.h b/OpenSky/arch/stm32f1/hal_dma.h
new file mode 100644
index 0000000..4629d4e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_dma.h
@@ -0,0 +1,6 @@
+#ifndef __HAL_DMA_H__
+#define __HAL_DMA_H__
+
+// NOTHING
+
+#endif
diff --git a/OpenSky/arch/stm32f1/hal_io.c b/OpenSky/arch/stm32f1/hal_io.c
new file mode 100644
index 0000000..bfac7d1
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_io.c
@@ -0,0 +1,54 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_io.h"
+#include "hal_defines.h"
+#include "config.h"
+#include "led.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_gpio.h"
+
+void hal_io_init(void) {
+ // configure bind io as input:
+ GPIO_InitTypeDef gpio_init;
+
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(BIND_JUMPER_GPIO_CLK_RCC, BIND_JUMPER_GPIO_CLK, ENABLE);
+
+ // configure bind input as pullup
+ gpio_init.GPIO_Pin = BIND_JUMPER_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(BIND_JUMPER_GPIO, &gpio_init);
+}
+
+uint8_t hal_io_bind_request(void) {
+ // Returs pin state (1 if HIGH, 0 if LOW)
+ if (GPIO_ReadInputDataBit(BIND_JUMPER_GPIO, BIND_JUMPER_PIN)) {
+ // HIGH -> button not pressed
+ return 0;
+ } else {
+ // LOW -> button pressed
+ return 1;
+ }
+}
+
+
+
+
diff --git a/OpenSky/arch/stm32f1/hal_io.h b/OpenSky/arch/stm32f1/hal_io.h
new file mode 100644
index 0000000..b0c1245
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_io.h
@@ -0,0 +1,28 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_IO_H_
+#define HAL_IO_H_
+
+#include
+
+void hal_io_init(void);
+uint8_t hal_io_bind_request(void);
+
+#endif // HAL_IO_H_
diff --git a/OpenSky/arch/stm32f1/hal_led.c b/OpenSky/arch/stm32f1/hal_led.c
new file mode 100644
index 0000000..b4951cb
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_led.c
@@ -0,0 +1,35 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_led.h"
+#include "hal_defines.h"
+#include "stm32f10x_rcc.h"
+
+void hal_led_init(uint16_t pin) {
+ GPIO_InitTypeDef gpio_init;
+
+ // periph clock enable for port
+ RCC_APBxPeriphClockCmd(LED_GPIO_CLK_RCC, LED_GPIO_CLK, ENABLE);
+
+ // configure led output as push-pull
+ gpio_init.GPIO_Pin = pin;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(LED_GPIO, &gpio_init);
+}
diff --git a/OpenSky/arch/stm32f1/hal_led.h b/OpenSky/arch/stm32f1/hal_led.h
new file mode 100644
index 0000000..d2aff39
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_led.h
@@ -0,0 +1,41 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_LED_H_
+#define HAL_LED_H_
+
+#include "stm32f10x_gpio.h"
+#include "config.h"
+
+void hal_led_init(uint16_t pin);
+
+#define hal_led_green_init() { hal_led_init(LED_GREEN_PIN); }
+#define hal_led_green_on() { LED_GPIO->BSRR = (LED_GREEN_PIN); }
+#define hal_led_green_off() { LED_GPIO->BRR = (LED_GREEN_PIN); }
+#define hal_led_green_toggle() { \
+ LED_GPIO->BSRR = (LED_GPIO->ODR ^ LED_GREEN_PIN) | (LED_GREEN_PIN << 16);}
+
+#define hal_led_red_init() { hal_led_init(LED_RED_PIN); }
+#define hal_led_red_on() { LED_GPIO->BSRR = (LED_RED_PIN); }
+#define hal_led_red_off() { LED_GPIO->BRR = (LED_RED_PIN); }
+#define hal_led_red_toggle() { \
+ LED_GPIO->BSRR = (LED_GPIO->ODR ^ LED_RED_PIN) | (LED_RED_PIN << 16);}
+
+#endif // HAL_LED_H_
+
diff --git a/OpenSky/arch/stm32f1/hal_ppm.c b/OpenSky/arch/stm32f1/hal_ppm.c
new file mode 100644
index 0000000..9b7b45b
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_ppm.c
@@ -0,0 +1,168 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_ppm.h"
+#include "ppm.h"
+#include "wdt.h"
+#include "led.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_tim.h"
+#include "misc.h" // stm32 nvic stuff
+
+#ifndef SBUS_ENABLED
+
+void hal_ppm_init(void) {
+ hal_ppm_init_rcc();
+ hal_ppm_init_gpio();
+ hal_ppm_init_timer();
+ hal_ppm_init_nvic();
+}
+
+static void hal_ppm_init_rcc(void) {
+ // PCLK = HCLK set in system init...
+ // do not set it here...
+
+ // timer clock enable */
+ RCC_APBxPeriphClockCmd(PPM_TIMER_CLK_RCC, PPM_TIMER_CLK, ENABLE);
+
+ // gpio clock
+ RCC_APBxPeriphClockCmd(PPM_GPIO_CLK_RCC, PPM_GPIO_CLK, ENABLE);
+
+ // afio clk
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
+}
+
+static void hal_ppm_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // activate AF for ppm gpio:
+ gpio_init.GPIO_Pin = PPM_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(PPM_GPIO, &gpio_init);
+}
+
+static void hal_ppm_init_timer(void) {
+ TIM_TimeBaseInitTypeDef tim_init;
+ TIM_OCInitTypeDef tim_oc_init;
+
+
+ TIM_TimeBaseStructInit(&tim_init);
+ // time base configuration: count to 1000us (will be set properly lateron)
+ tim_init.TIM_Period = HAL_PPM_US_TO_TICKCOUNT(1000);
+ // compute the prescaler value, we want a 0.5us resolution (= count with 2mhz):
+ tim_init.TIM_Prescaler = (uint16_t) (SystemCoreClock / 2000000) - 1;
+ tim_init.TIM_ClockDivision = 0;
+ tim_init.TIM_CounterMode = TIM_CounterMode_Up;
+
+ // set time base. NOTE: this will immediately trigger an INT!
+ TIM_TimeBaseInit(PPM_TIMER, &tim_init);
+
+ // clear IT flag (caused by TimeBaseInit()):
+ TIM_ClearITPendingBit(PPM_TIMER, TIM_IT_Update);
+
+ // Output Compare Active Mode configuration:
+ TIM_OCStructInit(&tim_oc_init);
+#ifdef PPM_INVERTED
+ tim_oc_init.TIM_OCMode = TIM_OCMode_PWM2;
+#else
+ tim_oc_init.TIM_OCMode = TIM_OCMode_PWM1;
+#endif // PPM_INVERTED
+ tim_oc_init.TIM_OutputState = TIM_OutputState_Enable;
+ tim_oc_init.TIM_Pulse = PPM_SYNC_PULS_LEN_TICKS;
+ tim_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;
+ hal_ppm_init_ocx(PPM_TIMER_CH, PPM_TIMER, &tim_oc_init);
+
+ // enable counter
+ TIM_Cmd(PPM_TIMER, ENABLE);
+}
+
+static void hal_ppm_init_nvic(void) {
+ NVIC_InitTypeDef nvic_init;
+
+ // strange, somehow the Timer IT Flags seem to be already enabled?!
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Update, DISABLE);
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Break, DISABLE);
+ TIM_ITConfig(PPM_TIMER, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, DISABLE);
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Trigger, DISABLE);
+
+ // enable timer interrupt
+ nvic_init.NVIC_IRQChannel = PPM_TIMER_IRQn;
+ nvic_init.NVIC_IRQChannelPreemptionPriority = NVIC_PRIO_PPM;
+ nvic_init.NVIC_IRQChannelSubPriority = 0;
+ nvic_init.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic_init);
+
+ // enable ONLY update interrupt
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Update, ENABLE);
+}
+
+void hal_ppm_failsafe_enter(void) {
+ // set output to static value ZERO
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Update, DISABLE);
+
+ // set output to static low or high level:
+ GPIO_InitTypeDef gpio_init;
+ gpio_init.GPIO_Pin = PPM_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(PPM_GPIO, &gpio_init);
+
+#if PPM_INVERTED
+ // clear on zero -> default is high
+ PPM_GPIO->BSRR = (PPM_PIN);
+#else
+ // set on zero -> default is low
+ PPM_GPIO->BRR = (PPM_PIN);
+#endif // PPM_INVERTED
+}
+
+void hal_ppm_failsafe_exit(void) {
+ // exit failsafe, back to pulse generation
+ hal_ppm_init_gpio();
+
+ // re-enable ppm output isr
+ TIM_ITConfig(PPM_TIMER, TIM_IT_Update, ENABLE);
+}
+
+static void hal_ppm_init_ocx(uint8_t ch, TIM_TypeDef *TIMx, TIM_OCInitTypeDef *tim_oc_init) {
+ switch (PPM_TIMER_CH) {
+ default:
+ break;
+ case(TIM_Channel_4):
+ TIM_OC4Init(TIMx, tim_oc_init);
+ TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Disable);
+ break;
+ case(TIM_Channel_3):
+ TIM_OC3Init(TIMx, tim_oc_init);
+ TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Disable);
+ break;
+ case(TIM_Channel_2):
+ TIM_OC2Init(TIMx, tim_oc_init);
+ TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Disable);
+ break;
+ case(TIM_Channel_1):
+ TIM_OC1Init(TIMx, tim_oc_init);
+ TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Disable);
+ break;
+ }
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/stm32f1/hal_ppm.h b/OpenSky/arch/stm32f1/hal_ppm.h
new file mode 100644
index 0000000..5068e4e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_ppm.h
@@ -0,0 +1,53 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_PPM_H_
+#define HAL_PPM_H_
+
+#include "config.h"
+#include "stm32f10x_tim.h"
+
+void hal_ppm_init(void);
+
+void hal_ppm_failsafe_exit(void);
+void hal_ppm_failsafe_enter(void);
+
+static void hal_ppm_init_rcc(void);
+static void hal_ppm_init_gpio(void);
+static void hal_ppm_init_timer(void);
+static void hal_ppm_init_nvic(void);
+static void hal_ppm_init_ocx(uint8_t ch, TIM_TypeDef *TIMx, TIM_OCInitTypeDef *tim_oc_init);
+
+// counter runs with 2MHz = 0.5us resolution
+#define HAL_PPM_US_TO_TICKCOUNT(us) ((us * 2)-1)
+// from frsky to ticks coresponding to 1000...2000 us
+// frsky seems to send us*1.5 (~1480...3020)
+// -> divide by 1.5 (=*2/3) to get us -> multiply by 2 to get us
+#define HAL_PPM_FRSKY_TO_TICKCOUNT(_frsky) ((_frsky)*2*2/3)
+
+#define PPM_TIMER_ISR(void) PPM_TIMER_IRQHANDLER(void)
+
+#define HAL_PPM_UPDATE_CCVALUE(x) { PPM_TIMER->ARR = x; }
+#define HAL_PPM_ISR_DISABLE() { __disable_irq(); }
+#define HAL_PPM_ISR_ENABLE() { __enable_irq(); }
+#define HAL_PPM_ISR_FLAG_SET() (TIM_GetITStatus(PPM_TIMER, TIM_IT_Update) != RESET)
+#define HAL_PPM_ISR_CLEAR_FLAG() { TIM_ClearITPendingBit(PPM_TIMER, TIM_IT_Update); }
+
+
+#endif // HAL_PPM_H_
diff --git a/OpenSky/arch/stm32f1/hal_sbus.c b/OpenSky/arch/stm32f1/hal_sbus.c
new file mode 100644
index 0000000..28a9efa
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_sbus.c
@@ -0,0 +1,20 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_sbus.h"
diff --git a/OpenSky/arch/stm32f1/hal_sbus.h b/OpenSky/arch/stm32f1/hal_sbus.h
new file mode 100644
index 0000000..3892d0e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_sbus.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SBUS_H_
+#define HAL_SBUS_H_
+
+// not used here
+#define HAL_SBUS_PREPARE_DATA(a) (a)
+
+#endif // HAL_SBUS_H_
diff --git a/OpenSky/arch/stm32f1/hal_soft_serial.c b/OpenSky/arch/stm32f1/hal_soft_serial.c
new file mode 100644
index 0000000..3e5ac44
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_soft_serial.c
@@ -0,0 +1,190 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_soft_serial.h"
+#include "debug.h"
+#include "config.h"
+#include "led.h"
+#include "soft_serial.h"
+#include "stm32f10x.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_tim.h"
+#include "misc.h" // stm32 nvic
+
+#ifndef HUB_TELEMETRY_ON_SBUS_UART
+
+void hal_soft_serial_init(void) {
+ hal_soft_serial_init_gpio();
+ hal_soft_serial_init_rcc();
+ hal_soft_serial_init_timer();
+ hal_soft_serial_init_nvic();
+}
+
+static void hal_soft_serial_init_rcc(void) {
+ // enable clocks
+ RCC_APBxPeriphClockCmd(SOFT_SERIAL_CLK_RCC, SOFT_SERIAL_CLK, ENABLE);
+ // timer clock enable
+ RCC_APBxPeriphClockCmd(SOFT_SERIAL_TIMER_CLK_RCC, SOFT_SERIAL_TIMER_CLK, ENABLE);
+ // release reset cmd (?)
+ RCC_APBxPeriphResetCmd(SOFT_SERIAL_TIMER_CLK_RCC, SOFT_SERIAL_TIMER_CLK, DISABLE);
+}
+
+static void hal_soft_serial_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // configure rx pin as input:
+ gpio_init.GPIO_Pin = SOFT_SERIAL_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init(SOFT_SERIAL_GPIO, &gpio_init);
+}
+
+
+static void hal_soft_serial_init_timer(void) {
+ TIM_TimeBaseInitTypeDef tim_init;
+ TIM_ICInitTypeDef tim_ic_init;
+
+ // time base configuration:
+ TIM_TimeBaseStructInit(&tim_init);
+ // this serial uart runs at 9600 baud, thus bitlength = 1/9600 = 104.166667 us
+ // a 1mhz counter gives us 1us resolution, a 24mhz counter gives us 1/24 us res
+ // the finer the better -> go for 24mhz counter = prescaler = 0 (:1)
+ tim_init.TIM_Prescaler = (uint16_t) (0);
+ // timer period = bit duration
+ tim_init.TIM_Period = 0xFFFF;
+ tim_init.TIM_ClockDivision = 0;
+ tim_init.TIM_CounterMode = TIM_CounterMode_Up;
+
+ // set time base. NOTE: this will immediately trigger an INT!
+ TIM_TimeBaseInit(SOFT_SERIAL_TIMER, &tim_init);
+
+ // clear IT flag (caused by TimeBaseInit()):
+ TIM_ClearITPendingBit(SOFT_SERIAL_TIMER, TIM_IT_Update);
+
+ TIM_ICStructInit(&tim_ic_init);
+ tim_ic_init.TIM_Channel = SOFT_SERIAL_TIMER_CH;
+#ifdef HUB_TELEMETRY_INVERTED
+ #ifdef SOFT_SERIAL_PIN_HAS_INVERTER
+ // board has inverter -> invert twice = no inversion
+ tim_ic_init.TIM_ICPolarity = TIM_ICPolarity_Falling;
+ #else
+ tim_ic_init.TIM_ICPolarity = TIM_ICPolarity_Rising;
+ #endif // SOFT_SERIAL_PIN_HAS_INVERTER
+#else
+ #ifdef SOFT_SERIAL_PIN_HAS_INVERTER
+ // board has inverter -> invert
+ tim_ic_init.TIM_ICPolarity = TIM_ICPolarity_Rising;
+ #else
+ tim_ic_init.TIM_ICPolarity = TIM_ICPolarity_Falling;
+ #endif // SOFT_SERIAL_PIN_HAS_INVERTER
+#endif // HUB_TELEMETRY_INVERTED
+ tim_ic_init.TIM_ICSelection = TIM_ICSelection_DirectTI;
+ tim_ic_init.TIM_ICPrescaler = TIM_ICPSC_DIV1;
+ tim_ic_init.TIM_ICFilter = 0x0;
+ TIM_ICInit(SOFT_SERIAL_TIMER, &tim_ic_init);
+
+ TIM_ClearITPendingBit(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC);
+/*
+ // Output Compare Active Mode configuration:
+ TIM_OCStructInit(&tim_oc_init);
+ tim_oc_init.TIM_OCMode = TIM_OCMode_ disable;
+ tim_oc_init.TIM_OutputState = TIM_OutputState_ disable;
+ tim_oc_init.TIM_Pulse = PPM_SYNC_PULS_LEN_TICKS;
+ tim_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;
+ hal_ppm_init_ocx(PPM_TIMER_CH, PPM_TIMER, &tim_oc_init);
+ */
+ // enable counter
+ TIM_Cmd(SOFT_SERIAL_TIMER, ENABLE);
+}
+
+
+static void hal_soft_serial_init_nvic(void) {
+ NVIC_InitTypeDef nvic_init;
+
+ // strange, somehow the Timer IT Flags seem to be already enabled?!
+ TIM_ITConfig(SOFT_SERIAL_TIMER, TIM_IT_Update, DISABLE);
+ TIM_ITConfig(SOFT_SERIAL_TIMER, TIM_IT_Break, DISABLE);
+ TIM_ITConfig(SOFT_SERIAL_TIMER, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, DISABLE);
+ TIM_ITConfig(SOFT_SERIAL_TIMER, TIM_IT_Trigger, DISABLE);
+
+ // enable input capture timer interrupt
+ nvic_init.NVIC_IRQChannel = SOFT_SERIAL_TIMER_IC_IRQn;
+ nvic_init.NVIC_IRQChannelPreemptionPriority = NVIC_PRIO_SOFT_SERIAL;
+ nvic_init.NVIC_IRQChannelSubPriority = 0;
+ nvic_init.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic_init);
+
+ // enable update timer interrupt
+ nvic_init.NVIC_IRQChannel = SOFT_SERIAL_TIMER_UP_IRQn;
+ nvic_init.NVIC_IRQChannelPreemptionPriority = NVIC_PRIO_SOFT_SERIAL;
+ nvic_init.NVIC_IRQChannelSubPriority = 0;
+ nvic_init.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic_init);
+
+
+ // for now enable ONLY the capture interrupt
+ TIM_ClearITPendingBit(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC);
+ TIM_ITConfig(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC, ENABLE);
+}
+
+
+void SOFT_SERIAL_TIMER_IC_IRQHandler(void) {
+ // handle startbit:
+ if (HAL_SOFT_SERIAL_IC_ISR_FLAG_SET()) {
+ // reset counter
+ TIM_SetCounter(SOFT_SERIAL_TIMER, 0);
+ // this is the startbit -> re synchronize the timer to this
+ // by setting the next cc interrupt to 1/2 bit length:
+ HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(HAL_SOFTSERIAL_BIT_DURATION_TICKS / 2);
+
+ // disable IC interrupt (only compare match interrupts will trigger this isr)
+ HAL_SOFT_SERIAL_IC_ISR_DISABLE();
+
+ // enable overflow isr
+ HAL_SOFT_SERIAL_UP_ISR_ENABLE();
+
+ // clear flag - NOTE: this should never be done at the end of the isr!
+ HAL_SOFT_SERIAL_IC_ISR_FLAG_CLEAR();
+ // clear any pending update flags as well
+ HAL_SOFT_SERIAL_UP_ISR_FLAG_CLEAR();
+
+ // process
+ soft_serial_process_startbit();
+ }
+}
+
+void SOFT_SERIAL_TIMER_UP_IRQHandler(void) {
+ if (HAL_SOFT_SERIAL_UP_ISR_FLAG_SET()) {
+ // clear flag - NOTE: this should never be done at the end of the isr!
+ HAL_SOFT_SERIAL_UP_ISR_FLAG_CLEAR();
+
+ // re-arm for the next bit
+ HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(HAL_SOFTSERIAL_BIT_DURATION_TICKS);
+
+ if (soft_serial_process_databit()) {
+ // finished transmission, disable UP and enable IC isr
+ HAL_SOFT_SERIAL_UP_ISR_DISABLE();
+ HAL_SOFT_SERIAL_IC_ISR_FLAG_CLEAR();
+ HAL_SOFT_SERIAL_IC_ISR_ENABLE();
+ }
+ }
+}
+
+#endif // if not HUB_TELEMETRY_ON_SBUS_UART
diff --git a/OpenSky/arch/stm32f1/hal_soft_serial.h b/OpenSky/arch/stm32f1/hal_soft_serial.h
new file mode 100644
index 0000000..9425174
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_soft_serial.h
@@ -0,0 +1,73 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SOFT_SERIAL_H_
+#define HAL_SOFT_SERIAL_H_
+
+#include "config.h"
+#include "soft_serial.h"
+#include "stm32f10x_gpio.h"
+
+
+// at 9600 baud a bit duration is 1/9600s = 104.166667us
+// the counter counts in 1/24th of us -> 104.1667us * 24 =
+#define HAL_SOFTSERIAL_BIT_DURATION_TICKS 2500
+
+void hal_soft_serial_init(void);
+
+static void hal_soft_serial_init_rcc(void);
+static void hal_soft_serial_init_gpio(void);
+static void hal_soft_serial_init_timer(void);
+static void hal_soft_serial_init_nvic(void);
+
+#define HUB_TELEMETRY_PIN_LO_RAW() (GPIO_ReadInputDataBit(SOFT_SERIAL_GPIO, SOFT_SERIAL_PIN) == 0)
+#define HUB_TELEMETRY_PIN_HI_RAW() (!HUB_TELEMETRY_PIN_LO_RAW())
+
+#ifdef SOFT_SERIAL_PIN_HAS_INVERTER
+ #define HUB_TELEMETRY_PIN_LO() HUB_TELEMETRY_PIN_HI_RAW()
+ #define HUB_TELEMETRY_PIN_HI() HUB_TELEMETRY_PIN_LO_RAW()
+#else
+ #define HUB_TELEMETRY_PIN_LO() HUB_TELEMETRY_PIN_LO_RAW()
+ #define HUB_TELEMETRY_PIN_HI() HUB_TELEMETRY_PIN_HI_RAW()
+#endif // SOFT_SERIAL_PIN_HAS_INVERTER
+
+#define HAL_SOFT_SERIAL_IC_ISR_DISABLE() {\
+ TIM_ITConfig(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC, DISABLE); }
+#define HAL_SOFT_SERIAL_IC_ISR_ENABLE() {\
+ TIM_ITConfig(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC, ENABLE); }
+#define HAL_SOFT_SERIAL_IC_ISR_FLAG_SET() \
+ (TIM_GetITStatus(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC) != RESET)
+#define HAL_SOFT_SERIAL_IC_ISR_FLAG_CLEAR() {\
+TIM_ClearITPendingBit(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_IC); }
+
+#define HAL_SOFT_SERIAL_UP_ISR_DISABLE() {\
+ TIM_ITConfig(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_UP, DISABLE); }
+#define HAL_SOFT_SERIAL_UP_ISR_ENABLE() {\
+TIM_ITConfig(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_UP, ENABLE); }
+#define HAL_SOFT_SERIAL_UP_ISR_FLAG_SET() \
+ (TIM_GetITStatus(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_UP) != RESET)
+#define HAL_SOFT_SERIAL_UP_ISR_FLAG_CLEAR() {\
+TIM_ClearITPendingBit(SOFT_SERIAL_TIMER, SOFT_SERIAL_TIMER_IT_UP); }
+
+#define HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(x) { SOFT_SERIAL_TIMER->ARR = x; }
+
+void SOFT_SERIAL_TIMER_IC_IRQHandler(void);
+void SOFT_SERIAL_TIMER_UP_IRQHandler(void);
+
+#endif // HAL_SOFT_SERIAL_H_
diff --git a/OpenSky/arch/stm32f1/hal_spi.c b/OpenSky/arch/stm32f1/hal_spi.c
new file mode 100644
index 0000000..dd3d8c2
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_spi.c
@@ -0,0 +1,194 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_spi.h"
+#include "debug.h"
+#include "led.h"
+#include "config.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_spi.h"
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_dma.h"
+
+
+void hal_spi_init(void) {
+ hal_spi_init_rcc();
+ hal_spi_init_gpio();
+ hal_spi_init_mode();
+ hal_spi_init_dma();
+ hal_spi_enable();
+}
+
+static void hal_spi_init_rcc(void) {
+ // enable clocks
+ RCC_APB2PeriphClockCmd(CC25XX_SPI_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
+ RCC_APBxPeriphClockCmd(CC25XX_SPI_CLK_RCC, CC25XX_SPI_CLK, ENABLE);
+}
+
+static void hal_spi_enable(void) {
+ SPI_Cmd(CC25XX_SPI, ENABLE);
+}
+
+static void hal_spi_init_mode(void) {
+ SPI_InitTypeDef spi_init;
+
+ // mode config
+ spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ spi_init.SPI_Mode = SPI_Mode_Master;
+ spi_init.SPI_DataSize = SPI_DataSize_8b;
+ spi_init.SPI_CPOL = SPI_CPOL_Low;
+ spi_init.SPI_CPHA = SPI_CPHA_1Edge;
+ spi_init.SPI_NSS = SPI_NSS_Soft;
+ spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // = 3 MHz
+ spi_init.SPI_FirstBit = SPI_FirstBit_MSB;
+ spi_init.SPI_CRCPolynomial = 7;
+ SPI_Init(CC25XX_SPI, &spi_init);
+}
+
+
+
+static void hal_spi_init_dma(void) {
+ DMA_InitTypeDef dma_init;
+
+ // Enable DMA1 Peripheral Clock
+ RCC_AHBPeriphClockCmd(CC25XX_SPI_DMA_CLOCK, ENABLE);
+
+ // Configure SPI RX Channel
+ dma_init.DMA_DIR = DMA_DIR_PeripheralSRC;
+ dma_init.DMA_PeripheralBaseAddr = (uint32_t)&CC25XX_SPI->DR;
+ dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+ dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ dma_init.DMA_MemoryBaseAddr = 0; // will be set later
+ dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+ dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ dma_init.DMA_BufferSize = 1; // will be set later
+ dma_init.DMA_Mode = DMA_Mode_Normal;
+ dma_init.DMA_Priority = DMA_Priority_VeryHigh;
+ dma_init.DMA_M2M = DMA_M2M_Disable;
+ DMA_Init(CC25XX_SPI_RX_DMA_CHANNEL, &dma_init);
+
+ // configure SPI TX Channel
+ dma_init.DMA_DIR = DMA_DIR_PeripheralDST;
+ dma_init.DMA_PeripheralBaseAddr = (uint32_t)&CC25XX_SPI->DR;
+ dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+ dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ dma_init.DMA_MemoryBaseAddr = 0; // will be set later
+ dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+ dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ dma_init.DMA_BufferSize = 1; // will be set later
+ dma_init.DMA_Mode = DMA_Mode_Normal;
+ dma_init.DMA_Priority = DMA_Priority_VeryHigh;
+ dma_init.DMA_M2M = DMA_M2M_Disable;
+ DMA_Init(CC25XX_SPI_TX_DMA_CHANNEL, &dma_init);
+
+ // start disabled
+ DMA_Cmd(CC25XX_SPI_TX_DMA_CHANNEL, DISABLE);
+ DMA_Cmd(CC25XX_SPI_RX_DMA_CHANNEL, DISABLE);
+}
+
+// data in buffer will be sent and will be overwritten with
+// the data read back from the spi slave
+void hal_spi_dma_xfer(uint8_t *buffer, uint8_t len) {
+ // debug("xfer "); debug_put_uint8(len); debug(")\n");
+
+ // TX: transfer buffer to slave
+ CC25XX_SPI_TX_DMA_CHANNEL->CMAR = (uint32_t)buffer;
+ CC25XX_SPI_TX_DMA_CHANNEL->CNDTR = len;
+
+ // RX: read back data from slave
+ CC25XX_SPI_RX_DMA_CHANNEL->CMAR = (uint32_t)buffer;
+ CC25XX_SPI_RX_DMA_CHANNEL->CNDTR = len;
+
+ // enable both dma
+ DMA_Cmd(CC25XX_SPI_RX_DMA_CHANNEL, ENABLE);
+ DMA_Cmd(CC25XX_SPI_TX_DMA_CHANNEL, ENABLE);
+
+ // debug("DMA EN\n"); debug_flush();
+
+ // trigger the SPI TX + RX dma
+ SPI_I2S_DMACmd(CC25XX_SPI, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE);
+
+ // debug("TRIG\n"); debug_flush();
+#if 0
+ // Wait until the command is sent to the DR
+ while (!DMA_GetFlagStatus(CC25XX_SPI_TX_DMA_TC_FLAG)) {}
+
+ // debug("ACTIVE\n"); debug_flush();
+
+ // wait for tx to be finished:
+ while (DMA_GetFlagStatus(CC25XX_SPI_TX_DMA_TC_FLAG)) {}
+ while (DMA_GetFlagStatus(CC25XX_SPI_RX_DMA_TC_FLAG)) {}
+
+ // wait for SPI to be no longer busy
+ while (SPI_I2S_GetFlagStatus(CC25XX_SPI, SPI_I2S_FLAG_BSY) != RESET) {}
+ // debug("!BUSY\n"); debug_flush();
+#endif // 0
+
+ while (SPI_I2S_GetFlagStatus(CC25XX_SPI, SPI_I2S_FLAG_TXE) == RESET) {}
+ while (SPI_I2S_GetFlagStatus(CC25XX_SPI, SPI_I2S_FLAG_BSY) != RESET) {}
+
+ // while ((SPI1->SR & 2) == 0); // wait while TXE flag is 0 (TX is not empty)
+ // while ((SPI1->SR & (1 << 7)) != 0); // wait while BSY flag is 1 (SPI is busy)
+
+ // disable DMA
+ DMA_Cmd(CC25XX_SPI_RX_DMA_CHANNEL, DISABLE);
+ DMA_Cmd(CC25XX_SPI_TX_DMA_CHANNEL, DISABLE);
+
+ // clear DMA flags
+ SPI_I2S_DMACmd(CC25XX_SPI, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, DISABLE);
+}
+
+
+static void hal_spi_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // configure SCK and MOSI pins as Alternate Function Push-Pull
+ gpio_init.GPIO_Pin = CC25XX_SPI_SCK_PIN | CC25XX_SPI_MOSI_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(CC25XX_SPI_GPIO, &gpio_init);
+
+ // configure CSN as Push-Pull
+ gpio_init.GPIO_Pin = CC25XX_SPI_CSN_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(CC25XX_SPI_GPIO, &gpio_init);
+
+ // configure MISO pin as Input floating
+ gpio_init.GPIO_Pin = CC25XX_SPI_MISO_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init(CC25XX_SPI_GPIO, &gpio_init);
+}
+
+uint8_t hal_spi_tx(uint8_t address) {
+ // wait for SPI Tx buffer empty
+ while (SPI_I2S_GetFlagStatus(CC25XX_SPI, SPI_I2S_FLAG_TXE) == RESET) {}
+ // send SPI data
+ SPI_I2S_SendData(CC25XX_SPI, address);
+
+ // read response
+ while (SPI_I2S_GetFlagStatus(CC25XX_SPI, SPI_I2S_FLAG_RXNE) == RESET) {}
+ uint8_t result = SPI_I2S_ReceiveData(CC25XX_SPI);
+ return result;
+}
+
+
+uint8_t hal_spi_rx(void) {
+ return hal_spi_tx(0xff);
+}
diff --git a/OpenSky/arch/stm32f1/hal_spi.h b/OpenSky/arch/stm32f1/hal_spi.h
new file mode 100644
index 0000000..5965586
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_spi.h
@@ -0,0 +1,40 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_SPI_H_
+#define HAL_SPI_H_
+
+#include
+#include "config.h"
+#include "delay.h"
+
+void hal_spi_init(void);
+static void hal_spi_init_gpio(void);
+static void hal_spi_init_mode(void);
+static void hal_spi_init_dma(void);
+static void hal_spi_init_rcc(void);
+static void hal_spi_enable(void);
+void hal_spi_dma_xfer(uint8_t *buffer, uint8_t len);
+#define hal_spi_csn_lo() { CC25XX_SPI_GPIO->BRR = (CC25XX_SPI_CSN_PIN); delay_us(1); }
+#define hal_spi_csn_hi() { delay_us(1); CC25XX_SPI_GPIO->BSRR = (CC25XX_SPI_CSN_PIN); }
+uint8_t hal_spi_tx(uint8_t address);
+uint8_t hal_spi_rx(void);
+uint8_t hal_spi_read_address(uint8_t address);
+
+#endif // HAL_SPI_H_
diff --git a/OpenSky/arch/stm32f1/hal_storage.c b/OpenSky/arch/stm32f1/hal_storage.c
new file mode 100644
index 0000000..0d978ab
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_storage.c
@@ -0,0 +1,485 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_storage.h"
+#include "delay.h"
+#include "debug.h"
+#include "timeout.h"
+#include "stm32f10x_i2c.h"
+#include "stm32f10x_rcc.h"
+
+#define HAL_STORAGE_I2C_DEBUG 1
+
+#define EEPROM_I2C_TIMEOUT 20
+#define EEPROM_I2C_FLAG_TIMEOUT 10
+
+void hal_storage_init(void) {
+ hal_storage_init_i2c();
+}
+
+void hal_storage_write(uint8_t *buffer, uint16_t len) {
+ // verify write size
+ if (!hal_storage_check_len(len)) return;
+
+ // disable write protection
+ hal_storage_wp_disable();
+ delay_ms(1);
+
+ // execute write
+ if (!hal_storage_i2c_write_buffer(0, buffer, (uint8_t)len)) {
+ debug("hal_storage: ERROR! failed to write buffer\n");
+ debug_flush();
+ }
+
+ // re-enable write protection
+ delay_ms(1);
+ hal_storage_wp_enable();
+}
+
+
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len) {
+ // verify read size
+ if (!hal_storage_check_len(len)) return;
+
+ if (!hal_storage_i2c_read_buffer(0, storage_ptr, (uint8_t)len)) {
+ debug("hal_storage: ERROR! failed to read buffer\n");
+ debug_flush();
+ }
+}
+
+static void hal_storage_init_i2c(void) {
+ // disable i2c:
+ I2C_Cmd(EEPROM_I2C, DISABLE);
+ I2C_DeInit(EEPROM_I2C);
+
+ hal_storage_init_i2c_rcc();
+ hal_storage_init_i2c_gpio();
+}
+
+
+static void hal_storage_init_i2c_rcc(void) {
+ // peripheral clock for i2c
+ RCC_APBxPeriphClockCmd(EEPROM_I2C_CLK_RCC, EEPROM_I2C_CLK, ENABLE);
+
+ // gpio clock
+ RCC_APBxPeriphClockCmd(EEPROM_GPIO_CLK_RCC, EEPROM_GPIO_CLK, ENABLE);
+}
+
+static void hal_storage_init_i2c_mode(void) {
+ I2C_InitTypeDef i2c_init;
+
+ i2c_init.I2C_Mode = I2C_Mode_I2C;
+ i2c_init.I2C_DutyCycle = I2C_DutyCycle_2;
+ i2c_init.I2C_OwnAddress1 = EEPROM_I2C_ADDRESS;
+ i2c_init.I2C_Ack = I2C_Ack_Enable;
+ i2c_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
+ i2c_init.I2C_ClockSpeed = 200000;
+
+ // apply I2C configuration
+ I2C_Init(EEPROM_I2C, &i2c_init);
+
+ // enable i2c
+ I2C_Cmd(EEPROM_I2C, ENABLE);
+}
+
+static void hal_storage_init_i2c_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+ uint8_t i;
+
+
+ // gpio init:
+ // reset i2c bus by setting clk as output and sending manual clock pulses
+ gpio_init.GPIO_Pin = EEPROM_I2C_SCL_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(EEPROM_GPIO, &gpio_init);
+ gpio_init.GPIO_Pin = EEPROM_I2C_SDA_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(EEPROM_GPIO, &gpio_init);
+
+ if (1) {
+ debug("hal_storage: freeing i2c bus with clock train\n");
+ debug_flush();
+
+ // send 100khz clock train for some 100ms
+ timeout_set(100);
+ while (!timeout_timed_out()) {
+ if (GPIO_ReadInputDataBit(EEPROM_GPIO, EEPROM_I2C_SDA_PIN) == 1) {
+ debug("hal_storage: i2c free again\n");
+ break;
+ }
+ EEPROM_GPIO->BSRR = EEPROM_I2C_SCL_PIN;
+ delay_us(10);
+ EEPROM_GPIO->BRR = EEPROM_I2C_SCL_PIN;
+ delay_us(10);
+ }
+
+ // send stop condition:
+ gpio_init.GPIO_Pin = EEPROM_I2C_SDA_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(EEPROM_GPIO, &gpio_init);
+
+ // clock is low
+ EEPROM_GPIO->BRR = EEPROM_I2C_SCL_PIN;
+ delay_us(10);
+ // sda = lo
+ EEPROM_GPIO->BRR = EEPROM_I2C_SDA_PIN;
+ delay_us(10);
+ // clock goes high
+ EEPROM_GPIO->BSRR = EEPROM_I2C_SCL_PIN;
+ delay_us(10);
+ }
+
+ // init mode before setting to AF
+ hal_storage_init_i2c_mode();
+
+ // SDA & SCL
+ gpio_init.GPIO_Pin = EEPROM_I2C_SDA_PIN | EEPROM_I2C_SCL_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_AF_OD;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(EEPROM_GPIO, &gpio_init);
+
+ // WP = write protection
+ gpio_init.GPIO_Pin = EEPROM_WP_PIN;
+ gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(EEPROM_GPIO, &gpio_init);
+
+ // WP = HI = protected
+ hal_storage_wp_enable();
+}
+
+static uint32_t hal_storage_check_len(uint16_t len) {
+ if (len > 255) {
+ debug("hal_storage: ERROR, invalid data len ");
+ debug_put_uint16(len);
+ debug(" (max is 255)!\n");
+ debug_flush();
+ // invalid
+ return 0;
+ } else {
+ // safe
+ return 1;
+ }
+}
+
+static uint32_t hal_storage_i2c_read_buffer(uint16_t address, uint8_t *buffer, uint8_t len) {
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: i2c read_buffer(0x");
+ debug_put_hex8(address>>8);
+ debug_put_hex8(address&0xFF);
+ debug(", ..., ");
+ debug_put_uint16(len);
+ debug(")\n");
+ debug_flush();
+ }
+
+ timeout_set(EEPROM_I2C_TIMEOUT);
+ while (I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BUSY)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: bus busy... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send start
+ I2C_GenerateSTART(EEPROM_I2C, ENABLE);
+
+ // set on EV5 and clear it (cleared by reading SR1 then writing to DR)
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: master flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send EEPROM address for write
+ I2C_Send7bitAddress(EEPROM_I2C, EEPROM_I2C_ADDRESS, I2C_Direction_Transmitter);
+
+ // test on EV6 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: transmitter flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send the EEPROM's internal address to read from: Only one byte address
+ I2C_SendData(EEPROM_I2C, address);
+
+ // test on EV8 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BTF) == RESET) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: btf flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+
+ // send START condition a second time
+ I2C_GenerateSTART(EEPROM_I2C, ENABLE);
+
+ // set on EV5 and clear it (cleared by reading SR1 then writing to DR)
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: master flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send address (READ)
+ I2C_Send7bitAddress(EEPROM_I2C, EEPROM_I2C_ADDRESS, I2C_Direction_Receiver);
+
+ // test on EV6 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: receiver flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: reading ");
+ debug_put_uint8(len);
+ debug("bytes: ");
+ debug_flush();
+ }
+
+ // do not use dma etc, we do not need highspeed. do polling:
+ uint16_t i;
+ for (i = 0; i < len; i++) {
+ // wait on ADDR flag to be set (ADDR is still not cleared at this level)
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ /* Test on EV7 and clear it */
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: byte rx error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // read byte received:
+ buffer[i] = I2C_ReceiveData(EEPROM_I2C);
+
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug_put_hex8(buffer[i]);
+ debug_putc(' ');
+ debug_flush();
+ }
+
+ if (i == (len-1)) {
+ // last byte? -> NACK
+ I2C_AcknowledgeConfig(EEPROM_I2C, DISABLE);
+ } else {
+ // more bytes -> ACK
+ I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);
+ }
+
+
+ // wait for read to finish
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT*100);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_SLAVE_BYTE_RECEIVED)) {
+ // while (I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_RXNE) == RESET) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: read error... timeout!\n");
+ return 0;
+ }
+ }
+ }
+
+ // stop transmission
+ // clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
+ (void)EEPROM_I2C->SR2;
+
+ // send STOP Condition
+ I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
+
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug(". done.\n");
+ debug_flush();
+ }
+
+ // wait to make sure that STOP control bit has been cleared
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (EEPROM_I2C->CR1 & I2C_CR1_STOP) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: stop flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // re-enable Acknowledgement to be ready for another reception
+ I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);
+
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: read done\n");
+ debug_flush();
+ }
+
+ return 1;
+}
+
+static uint32_t hal_storage_i2c_write_buffer(uint8_t address, uint8_t *buffer, uint8_t len) {
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: i2c write_buffer(0x");
+ debug_put_hex8(address>>8);
+ debug_put_hex8(address&0xFF);
+ debug(", ..., ");
+ debug_put_uint16(len);
+ debug(")\n");
+ debug_flush();
+ }
+
+ uint8_t i;
+
+ // check for out of bound condition
+ uint16_t last_byte = (uint16_t)address + (uint16_t) len;
+ if (last_byte > 255) {
+ debug("hal_storage: ERROR write request invalid. out of memory!\n");
+ debug_flush();
+ return 0;
+ }
+
+ // write data
+ for (i = 0; i < len; i++) {
+ if (!hal_storage_i2c_write_byte(address + i, buffer[i])) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+// single byte write is slow and ugly but will do
+// we only use this once during binding...
+static uint32_t hal_storage_i2c_write_byte(uint8_t address, uint8_t data) {
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: i2c write_byte(0x");
+ debug_put_hex8(address>>8);
+ debug_put_hex8(address&0xFF);
+ debug(", 0x");
+ debug_put_hex8(data);
+ debug(")\n");
+ debug_flush();
+ }
+
+ timeout_set(EEPROM_I2C_TIMEOUT);
+ while (I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BUSY)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: bus busy... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send start
+ I2C_GenerateSTART(EEPROM_I2C, ENABLE);
+
+ // set on EV5 and clear it (cleared by reading SR1 then writing to DR)
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: master flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send EEPROM address for write
+ I2C_Send7bitAddress(EEPROM_I2C, EEPROM_I2C_ADDRESS, I2C_Direction_Transmitter);
+
+ // test on EV6 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: transmitter flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send the EEPROM's internal address to write to
+ I2C_SendData(EEPROM_I2C, address);
+
+ // test on EV8 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: address tx error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // send data byte
+ I2C_SendData(EEPROM_I2C, data);
+
+ // test on EV8 and clear it
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: data tx error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // stop transmission
+ // clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
+ (void)EEPROM_I2C->SR2;
+
+ // send STOP Condition
+ I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
+
+ // wait to make sure that STOP control bit has been cleared
+ timeout_set(EEPROM_I2C_FLAG_TIMEOUT);
+
+ while (EEPROM_I2C->CR1 & I2C_CR1_STOP) {
+ if (timeout_timed_out()) {
+ debug("hal_i2c: stop flag error... timeout!\n");
+ return 0;
+ }
+ }
+
+ // wait for write cycle time (5ms)
+ delay_ms(5+1);
+
+ if (HAL_STORAGE_I2C_DEBUG) {
+ debug("hal_storage: write done\n");
+ debug_flush();
+ }
+
+ return 1;
+}
+
+
diff --git a/OpenSky/arch/stm32f1/hal_storage.h b/OpenSky/arch/stm32f1/hal_storage.h
new file mode 100644
index 0000000..c97cd19
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_storage.h
@@ -0,0 +1,45 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_STORAGE_H_
+#define HAL_STORAGE_H_
+
+#include
+#include "config.h"
+#include "stm32f10x_gpio.h"
+
+void hal_storage_init(void);
+void hal_storage_write(uint8_t *buffer, uint16_t len);
+void hal_storage_read(uint8_t *storage_ptr, uint16_t len);
+
+static void hal_storage_init_i2c(void);
+static void hal_storage_init_i2c_mode(void);
+static void hal_storage_init_i2c_gpio(void);
+static void hal_storage_init_i2c_rcc(void);
+static uint32_t hal_storage_check_len(uint16_t len);
+static uint32_t hal_storage_i2c_read_buffer(uint16_t address, uint8_t *buffer, uint8_t len);
+static uint32_t hal_storage_i2c_write_buffer(uint8_t address, uint8_t *buffer, uint8_t len);
+static uint32_t hal_storage_i2c_write_byte(uint8_t address, uint8_t data);
+
+
+#define hal_storage_wp_enable() { EEPROM_GPIO->BSRR = EEPROM_WP_PIN; }
+#define hal_storage_wp_disable() { EEPROM_GPIO->BRR = EEPROM_WP_PIN; }
+
+
+#endif // HAL_STORAGE_H_
diff --git a/OpenSky/arch/stm32f1/hal_timeout.c b/OpenSky/arch/stm32f1/hal_timeout.c
new file mode 100644
index 0000000..64fe055
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_timeout.c
@@ -0,0 +1,95 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_timeout.h"
+#include "debug.h"
+#include "wdt.h"
+
+volatile static __IO uint32_t hal_timeout_100us;
+volatile static __IO uint32_t hal_timeout2_100us;
+volatile static __IO uint32_t hal_timeout_100us_delay;
+
+void hal_timeout_init(void) {
+ // configure 1ms sys tick:
+ if (SysTick_Config(SystemCoreClock / 10000)) {
+ debug("hal_timeout: failed to set systick timeout\n");
+ }
+
+ // set prio
+ NVIC_SetPriority(SysTick_IRQn, NVIC_PRIO_SYSTICK);
+
+ hal_timeout_100us = 0;
+ hal_timeout2_100us = 0;
+ hal_timeout_100us_delay = 0;
+}
+
+void hal_timeout_set_100us(__IO uint32_t hus) {
+ hal_timeout_100us = hus;
+}
+
+void hal_timeout2_set_100us(__IO uint32_t hus) {
+ hal_timeout2_100us = hus;
+}
+
+void hal_timeout_set(__IO uint32_t ms) {
+ hal_timeout_100us = 10*ms;
+}
+
+uint8_t hal_timeout_timed_out(void) {
+ // debug_put_uint16(hal_timeout_ms); debug("\n"); debug_flush();
+ return (hal_timeout_100us == 0);
+}
+
+uint8_t hal_timeout2_timed_out(void) {
+ // debug_put_uint16(hal_timeout_ms); debug("\n"); debug_flush();
+ return (hal_timeout2_100us == 0);
+}
+
+
+// seperate ms delay function
+void hal_timeout_delay_ms(uint32_t timeout) {
+ hal_timeout_100us_delay = 10*timeout;
+
+ while (hal_timeout_100us_delay > 0) {
+ }
+}
+
+/*// seperate ms delay function
+void hal_timeout_delay_100us(uint32_t timeout) {
+ hal_timeout_100us_delay = timeout;
+
+ while (hal_timeout_100us_delay > 0) {
+ }
+}*/
+
+void SysTick_Handler(void) {
+ if (hal_timeout_100us != 0) {
+ hal_timeout_100us--;
+ }
+ if (hal_timeout_100us_delay != 0) {
+ hal_timeout_100us_delay--;
+ }
+ if (hal_timeout2_100us != 0) {
+ hal_timeout2_100us--;
+ }
+}
+
+uint32_t hal_timeout_time_remaining(void) {
+ return hal_timeout_100us/10;
+}
diff --git a/OpenSky/arch/stm32f1/hal_timeout.h b/OpenSky/arch/stm32f1/hal_timeout.h
new file mode 100644
index 0000000..fc773e7
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_timeout.h
@@ -0,0 +1,39 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_TIMEOUT_H_
+#define HAL_TIMEOUT_H_
+
+#include "stm32f10x.h"
+
+void hal_timeout_init(void);
+void hal_timeout_set(__IO uint32_t ms);
+void hal_timeout_set_100us(__IO uint32_t hus);
+uint8_t hal_timeout_timed_out(void);
+void hal_timeout_delay_ms(uint32_t timeout);
+
+void hal_timeout2_set(__IO uint32_t ms);
+void hal_timeout2_set_100us(__IO uint32_t hus);
+uint8_t hal_timeout2_timed_out(void);
+
+uint32_t hal_timeout_time_remaining(void);
+
+void SysTick_Handler(void);
+
+#endif // HAL_TIMEOUT_H_
diff --git a/OpenSky/arch/stm32f1/hal_uart.c b/OpenSky/arch/stm32f1/hal_uart.c
new file mode 100644
index 0000000..0cab03e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_uart.c
@@ -0,0 +1,147 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_uart.h"
+#include "debug.h"
+#include "main.h"
+#include "sbus.h"
+#include "delay.h"
+#include "config.h"
+#include "hal_defines.h"
+#include "stm32f10x_usart.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_rcc.h"
+#include "misc.h" // this defines stm32 nvic stuff
+#include "uart.h"
+
+#ifdef SBUS_ENABLED
+
+volatile uint8_t hal_uart_tx_pos;
+volatile uint8_t *hal_uart_tx_buffer;
+
+void hal_uart_init(EXTERNAL_MEMORY uint8_t *data_ptr) {
+ hal_uart_init_rcc();
+ hal_uart_init_gpio();
+ hal_uart_init_nvic();
+ hal_uart_init_mode();
+}
+
+void SBUS_USART_IRQHANDLER(void) {
+ if (USART_GetITStatus(SBUS_USART, USART_IT_TXE) != RESET) {
+ // TXE interrupt
+ // finished with sending?
+ if (hal_uart_tx_pos >= SBUS_DATA_LEN) {
+ // no data in fifo -> disable tx int:
+ USART_ITConfig(SBUS_USART, USART_IT_TXE, DISABLE);
+ // debug_put_newline();
+ } else {
+ // else: data to tx
+ // debug_put_hex8(hal_uart_tx_buffer[hal_uart_tx_pos]);
+ USART_SendData(SBUS_USART, hal_uart_tx_buffer[hal_uart_tx_pos++]);
+ }
+ }
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+ if (USART_GetITStatus(SBUS_USART, USART_IT_RXNE) != RESET) {
+ // RXE interrupt
+ uint8_t rx = USART_ReceiveData(SBUS_USART);
+
+ if (uart_rx_callback != 0) {
+ // execute callback
+ uart_rx_callback(rx);
+ }
+ }
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+}
+
+
+static void hal_uart_init_nvic(void) {
+ // enable interrupts
+ NVIC_InitTypeDef nvic_init;
+
+ // configure the NVIC Preemption Priority Bits
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
+
+ // enable the USART interrupt
+ nvic_init.NVIC_IRQChannel = SBUS_USART_IRQn;
+ nvic_init.NVIC_IRQChannelPreemptionPriority = NVIC_PRIO_SBUS;
+ nvic_init.NVIC_IRQChannelSubPriority = 0;
+ nvic_init.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic_init);
+}
+
+static void hal_uart_init_gpio(void) {
+ GPIO_InitTypeDef gpio_init;
+
+ // Configure USART TX as alternate function push-pull
+ gpio_init.GPIO_Pin = SBUS_USART_TX_PIN;
+ gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
+ gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(SBUS_USART_GPIO, &gpio_init);
+}
+
+static void hal_uart_init_rcc(void) {
+ // configure clocks for uart:
+ // enable GPIO clock
+ RCC_APBxPeriphClockCmd(SBUS_USART_GPIO_CLK_RCC, SBUS_USART_GPIO_CLK, ENABLE);
+ RCC_APBxPeriphClockCmd(2, RCC_APB2Periph_AFIO, ENABLE);
+
+ // enable USART clock
+ RCC_APBxPeriphClockCmd(SBUS_USART_RCC, SBUS_USART_CLK, ENABLE);
+}
+
+static void hal_uart_init_mode(void) {
+ USART_InitTypeDef uart_init;
+
+ // USART configuration:
+ // 100000bps inverted serial stream, 8 bits, even parity, 2 stop bits
+ // no hw flow control
+ uart_init.USART_BaudRate = 100000;
+ // THIS IS TRICKY! for parity bit we need to set uart to 9 bit mode !
+ uart_init.USART_WordLength = USART_WordLength_9b;
+ uart_init.USART_StopBits = USART_StopBits_2;
+ uart_init.USART_Parity = USART_Parity_Even;
+ uart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ uart_init.USART_Mode = USART_Mode_Tx;
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+ uart_init.USART_Mode |= USART_Mode_Rx;
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+
+ USART_Init(SBUS_USART, &uart_init);
+
+ USART_Cmd(SBUS_USART, ENABLE);
+
+#ifdef HUB_TELEMETRY_ON_SBUS_UART
+ USART_ITConfig(SBUS_USART, USART_IT_RXNE, ENABLE);
+#endif // HUB_TELEMETRY_ON_SBUS_UART
+}
+
+void hal_uart_start_transmission(uint8_t *buffer, uint8_t len) {
+ // copy data ptr:
+ hal_uart_tx_buffer = buffer;
+
+ // set up counter:
+ hal_uart_tx_pos = 0;
+
+ // enable TXE int
+ USART_ITConfig(SBUS_USART, USART_IT_TXE, ENABLE);
+}
+
+#endif // SBUS_ENABLED
diff --git a/OpenSky/arch/stm32f1/hal_uart.h b/OpenSky/arch/stm32f1/hal_uart.h
new file mode 100644
index 0000000..1b50c7e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_uart.h
@@ -0,0 +1,35 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_UART_H_
+#define HAL_UART_H_
+
+#include
+#include "hal_defines.h"
+
+void hal_uart_init();
+static void hal_uart_init_gpio(void);
+static void hal_uart_init_rcc(void);
+static void hal_uart_init_mode(void);
+static void hal_uart_init_nvic(void);
+void hal_uart_start_transmission(uint8_t *buffer, uint8_t len);
+
+void SBUS_USART_IRQHANDLER(void);
+
+#endif // HAL_UART_H_
diff --git a/OpenSky/arch/stm32f1/hal_wdt.c b/OpenSky/arch/stm32f1/hal_wdt.c
new file mode 100644
index 0000000..b90ca22
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_wdt.c
@@ -0,0 +1,58 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#include "hal_wdt.h"
+#include "debug.h"
+#include "delay.h"
+#include "stm32f10x_iwdg.h"
+#include "stm32f10x_rcc.h"
+
+void hal_wdt_init(void) {
+ // detect resets from wdt
+ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) {
+ debug("hal_wdt: watchdog reset detected\n"); debug_flush();
+ RCC_ClearFlag();
+ }
+
+ // set iwdg timeout to roughly 1000ms (varies due to LSI freq dispersion)
+ uint32_t timeout_ms = 1000;
+
+ // enable write access to IWDG_PR and IWDG_RLR registers
+ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
+
+ // IWDG counter clock: LSI/32
+ IWDG_SetPrescaler(IWDG_Prescaler_32);
+
+ // set counter reload value
+ // 250ms timeout -> reload value = 0.25 * (LSI/32) = 0.25 * 40000 / 32 = 312.5
+ // --> 1ms = 312.5 / 250 = 1.25 = 5/4
+ IWDG_SetReload(timeout_ms * 5 / 4);
+
+ // reload IWDG counter
+ IWDG_ReloadCounter();
+
+ // enable IWDG (the LSI oscillator will be enabled by hardware)
+ IWDG_Enable();
+}
+
+inline void hal_wdt_reset(void) {
+ // reset wdt
+ IWDG_ReloadCounter();
+}
+
diff --git a/OpenSky/arch/stm32f1/hal_wdt.h b/OpenSky/arch/stm32f1/hal_wdt.h
new file mode 100644
index 0000000..d0fee38
--- /dev/null
+++ b/OpenSky/arch/stm32f1/hal_wdt.h
@@ -0,0 +1,26 @@
+/*
+ Copyright 2017 fishpepper gmail.com
+
+ 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 .
+
+ author: fishpepper gmail.com
+*/
+
+#ifndef HAL_WDT_H_
+#define HAL_WDT_H_
+
+void hal_wdt_init(void);
+void hal_wdt_reset(void);
+
+#endif // HAL_WDT_H_
diff --git a/OpenSky/arch/stm32f1/linker/stm32f103c8.ld b/OpenSky/arch/stm32f1/linker/stm32f103c8.ld
new file mode 100644
index 0000000..a7d903f
--- /dev/null
+++ b/OpenSky/arch/stm32f1/linker/stm32f103c8.ld
@@ -0,0 +1,186 @@
+/*
+Linker script for STM32F103C8_64K_20K
+
+modified from
+
+http://www.codesourcery.com/archives/arm-gnu/msg02972.html
+http://communities.mentor.com/community/cs/archives/arm-gnu/msg02972.html
+*/
+
+/*
+There will be a link error if there is not this amount of RAM free at the
+end.
+*/
+
+_Minimum_Stack_Size = 256;
+
+ENTRY(Reset_Handler)
+
+
+/* Memory Spaces Definitions */
+
+MEMORY
+{
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
+}
+
+__ram_start__ = ORIGIN(RAM);
+__ram_size__ = LENGTH(RAM);
+__ram_end__ = __ram_start__ + __ram_size__;
+_estack = __ram_end__;
+/* highest address of the user mode stack */
+
+
+
+PROVIDE ( _Stack_Limit = _estack - _Minimum_Stack_Size );
+
+/* Sections Definitions */
+
+SECTIONS
+{
+ .text :
+ {
+ KEEP(*(.isr_vector)) /* Startup code */
+ *(.text) /* code */
+ *(.text.*) /* remaining code */
+ *(.rodata) /* read-only data (constants) */
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.vfp11_veneer)
+ *(.v4_bx)
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } >FLASH
+
+ /* for exception handling/unwind - some Newlib functions (in
+ common with C++ and STDC++) use this. */
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+ __exidx_end = .;
+
+ . = ALIGN(4);
+ _etext = .;
+ /* This is used by the startup in order to initialize the .data secion
+*/
+ _sidata = _etext;
+
+ /* This is the initialized data section
+ The program executes knowing that the data is in the RAM
+ but the loader puts the initial values in the FLASH (inidata).
+ It is one task of the startup to copy the initial values from FLASH to
+RAM. */
+ .data : AT ( _sidata )
+ {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .data
+secion */
+ _sdata = . ;
+
+ *(.data)
+ *(.data.*)
+
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .data
+secion */
+ _edata = . ;
+ } >RAM
+
+
+ /* This is the uninitialized data section */
+ .bss :
+ {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss
+secion */
+ _sbss = .;
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss
+secion */
+ _ebss = . ;
+ __bss_end__ = _ebss;
+ } >RAM
+
+ PROVIDE ( end = _ebss );
+ PROVIDE ( _end = _ebss );
+ PROVIDE ( _exit = _ebss );
+ PROVIDE (_stackend = ORIGIN(RAM) + LENGTH(RAM) - _Minimum_Stack_Size);
+
+ /* This is the user stack section
+ This is just to check that there is enough RAM left for the User mode
+stack
+ It should generate an error if it's full.
+ */
+ ._usrstack :
+ {
+ . = ALIGN(4);
+ _susrstack = . ;
+
+ . = . + _Minimum_Stack_Size ;
+
+ . = ALIGN(4);
+ _eusrstack = . ;
+ } >RAM
+
+
+
+ /* after that it's only debugging information. */
+
+ /* remove the debugging information from the standard libraries */
+/*
+ DISCARD :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+*/
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
diff --git a/OpenSky/arch/stm32f1/peripheral_lib/Release_Notes.html b/OpenSky/arch/stm32f1/peripheral_lib/Release_Notes.html
new file mode 100644
index 0000000..633e42e
--- /dev/null
+++ b/OpenSky/arch/stm32f1/peripheral_lib/Release_Notes.html
@@ -0,0 +1,342 @@
+
+
+
+
+
+
+
+
+
+
+
+
+Release Notes for STM32F10x Standard Peripherals Library Drivers
+
+
+
+
+
+