This commit is contained in:
Conor Patrick 2019-02-26 13:10:16 -05:00
commit 1a6895ca25
183 changed files with 1790 additions and 60387 deletions

View File

@ -1,4 +0,0 @@
{
"contributors": "https://raw.githubusercontent.com/solokeys/contributors/master/contributors.json",
"message": "We require contributors to sign our Copyright License Agreement, and we don't have {{usersWithoutCLA}} on file. In order for us to review and merge your code, please visit https://solokeys.com/legal/contributors, or contact @nickray, @conorpp or @0x0ece for further information or help."
}

1
.envrc Normal file
View File

@ -0,0 +1 @@
source venv/bin/activate

1
.gitignore vendored
View File

@ -74,6 +74,7 @@ tools/python-fido2/*
*.key
site/
_site/
venv/
env2/
env3/
.project

View File

@ -8,6 +8,12 @@ addons:
packages:
- gcc-7
- cppcheck
before_install:
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -q
- sudo apt-get install -y gcc-arm-embedded
- sudo apt-get install -y python3-venv
script:
- export CC=gcc-7
- make test
- pyenv shell 3.6.7
- make travis

View File

@ -7,11 +7,22 @@ ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ENV{ID_MM_DEVICE_IGNORE}="1"
LABEL="mm_usb_device_blacklist_end"
# Solo
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo HACKER (Unlocked)", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solohacker"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey-serial"
# Solo
## bootloader + firmware access
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev"
## DFU access
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", TAG+="uaccess", GROUP="plugdev"
## Solo Secure symlink
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo [1-9]*", SYMLINK+="solokey"
## Solo Hacker symlink
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo Hacker [1-9]*", SYMLINK+="solohacker"
## Solo Serial access + symlink
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", SYMLINK+="soloserial"
# U2F Zero
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero"

17
CHANGELOG.md Normal file
View File

@ -0,0 +1,17 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.1.0] - 2019-02-17
### Added
- Code cleanup
- Buffer over-read bug fix
- U2F counter endianness bug fix
- More testing
- Extension interface to U2F and FIDO2
- Read firmware version
- Read RNG bytes

31
Dockerfile Normal file
View File

@ -0,0 +1,31 @@
FROM debian:stretch-slim
MAINTAINER SoloKeys <hello@solokeys.com>
RUN apt-get update -qq
RUN apt-get install -qq bzip2 git make wget >/dev/null
# 1. ARM GCC: for compilation
RUN wget -q -O gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2?revision=d830f9dd-cd4f-406d-8672-cca9210dd220?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,8-2018-q4-major
# from website
RUN echo "f55f90d483ddb3bcf4dae5882c2094cd gcc.tar.bz2" > gcc.md5
RUN md5sum -c gcc.md5
# self-generated
RUN echo "fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52 gcc.tar.bz2" > gcc.sha256
RUN sha256sum -c gcc.sha256
RUN tar -C /opt -xf gcc.tar.bz2
# 2. Python3.7: for solotool (merging etc.)
RUN wget -q -O miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-4.5.12-Linux-x86_64.sh
# from website
RUN echo "866ae9dff53ad0874e1d1a60b1ad1ef8 miniconda.sh" > miniconda.md5
RUN md5sum -c miniconda.md5
# self-generated
RUN echo "e5e5b4cd2a918e0e96b395534222773f7241dc59d776db1b9f7fedfcb489157a miniconda.sh" > miniconda.sha256
RUN sha256sum -c miniconda.sha256
RUN bash ./miniconda.sh -b -p /opt/conda
RUN ln -s /opt/conda/bin/python3 /usr/local/bin/python3
RUN ln -s /opt/conda/bin/python3 /usr/local/bin/python
# 3. Source code
RUN git clone --recurse-submodules https://github.com/solokeys/solo /solo --config core.autocrlf=input

619
LICENSE
View File

@ -1,619 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
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.

201
LICENSE-APACHE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

23
LICENSE-MIT Normal file
View File

@ -0,0 +1,23 @@
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -9,11 +9,8 @@
ecc_platform=2
EFM32_DEBUGGER= -s 440083537 --device EFM32JG1B200F128GM32
#EFM32_DEBUGGER= -s 440121060 #dev board
src = $(wildcard pc/*.c) $(wildcard fido2/*.c) $(wildcard crypto/sha256/*.c) crypto/tiny-AES-c/aes.c
obj = $(src:.c=.o) uECC.o
obj = $(src:.c=.o) crypto/micro-ecc/uECC.o
LIBCBOR = tinycbor/lib/libtinycbor.a
@ -33,7 +30,7 @@ CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\"
name = main
.PHONY: all
.PHONY: all $(LIBCBOR) black blackcheck cppcheck wink fido2-test clean full-clean travis test clean version
all: main
tinycbor/Makefile crypto/tiny-AES-c/aes.c:
@ -42,52 +39,48 @@ tinycbor/Makefile crypto/tiny-AES-c/aes.c:
.PHONY: cbor
cbor: $(LIBCBOR)
$(LIBCBOR): tinycbor/Makefile
$(LIBCBOR):
cd tinycbor/ && $(MAKE) clean && $(MAKE) -j8
.PHONY: efm8prog
efm8prog:
cd './targets/efm8\Keil 8051 v9.53 - Debug' && $(MAKE) all
flashefm8.exe -part EFM8UB10F8G -sn 440105518 -erase
flashefm8.exe -part EFM8UB10F8G -sn 440105518 -upload './targets/efm8/Keil 8051 v9.53 - Debug/efm8.hex'
version:
@git describe
.PHONY: efm32com efm32prog efm32read efm32bootprog
efm32com:
cd './targets/efm32/GNU ARM v7.2.1 - Debug' && $(MAKE) all
efm32prog: efm32com
commander flash './targets/efm32/GNU ARM v7.2.1 - Debug/EFM32.hex' $(EFM32_DEBUGGER) -p "0x1E7FC:0x00000000:4"
efm32read: efm32com
commander swo read $(EFM32_DEBUGGER)
efm32bootprog: efm32com
commander flash './efm32boot/GNU ARM v7.2.1 - Debug/efm32boot.hex' $(EFM32_DEBUGGER) --masserase
test: venv
$(MAKE) clean
$(MAKE) -C . main
$(MAKE) clean
$(MAKE) -C ./targets/stm32l432 test PREFIX=$(PREFIX) "VENV=$(VENV)"
$(MAKE) clean
$(MAKE) cppcheck
$(name): $(obj) $(LIBCBOR)
$(CC) $(LDFLAGS) -o $@ $(obj) $(LDFLAGS)
uECC.o: ./crypto/micro-ecc/uECC.c
crypto/micro-ecc/uECC.o: ./crypto/micro-ecc/uECC.c
$(CC) -c -o $@ $^ -O2 -fdata-sections -ffunction-sections -DuECC_PLATFORM=$(ecc_platform) -I./crypto/micro-ecc/
env2:
virtualenv --python=python2.7 env2
env2/bin/pip install --upgrade -r tools/requirements.txt
env3:
python3 -m venv env3
env3/bin/pip install --upgrade -r tools/requirements.txt
env3/bin/pip install --upgrade black
venv:
python3 -m venv venv
venv/bin/pip -q install --upgrade -r tools/requirements.txt
venv/bin/pip -q install --upgrade black
# selectively reformat our own code
black: env3
env3/bin/black --skip-string-normalization tools/
black: venv
venv/bin/black --skip-string-normalization --check tools/
wink2: env2
env2/bin/python tools/solotool.py solo --wink
wink: venv
venv/bin/python tools/solotool.py solo --wink
wink3: env3
env3/bin/python tools/solotool.py solo --wink
fido2-test: venv
venv/bin/python tools/ctap_test.py
fido2-test: env3
env3/bin/python tools/ctap_test.py
DOCKER_IMAGE := "solokeys/solo-firmware:local"
SOLO_VERSIONISH := "master"
docker-build:
docker build -t $(DOCKER_IMAGE) .
docker run --rm -v "$(CURDIR)/builds:/builds" \
-v "$(CURDIR)/in-docker-build.sh:/in-docker-build.sh" \
$(DOCKER_IMAGE) /in-docker-build.sh $(SOLO_VERSIONISH)
CPPCHECK_FLAGS=--quiet --error-exitcode=2
@ -97,13 +90,17 @@ cppcheck:
cppcheck $(CPPCHECK_FLAGS) fido2
cppcheck $(CPPCHECK_FLAGS) pc
test: main cppcheck
clean:
rm -f *.o main.exe main $(obj)
rm -rf env2 env3
for f in crypto/tiny-AES-c/Makefile tinycbor/Makefile ; do \
if [ -f "$$f" ]; then \
(cd `dirname $$f` ; git checkout -- .) ;\
fi ;\
done
full-clean: clean
rm -rf venv
travis:
$(MAKE) test VENV=". ../../venv/bin/activate;"
$(MAKE) black

View File

@ -35,7 +35,7 @@ Solo for Hacker is a special version of Solo that let you customize its firmware
You can only buy Solo for Hacker at [solokeys.com](https://solokeys.com), as we don't sell it on Amazon and other places to avoid confusing customers. If you buy a Hacker, you can permanently lock it into a regular Solo, but viceversa you can NOT take a regular Solo and turn it a Hacker.
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/).
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/). We only support Python3.
```bash
git clone --recurse-submodules https://github.com/solokeys/solo
@ -43,14 +43,16 @@ cd solo
cd targets/stm32l432
make cbor
make all-hacker
make build-hacker
cd ../..
make env3
source env3/bin/activate
make venv
source venv/bin/activate
python tools/solotool.py program targets/stm32l432/solo.hex
```
Alternatively, run `make docker-build` and use the firmware generated in `/tmp`.
If you forgot the `--recurse-submodules` when cloning, simply `git submodule update --init --recursive`.
For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/led.c#L15) and force:
@ -118,9 +120,8 @@ Look at the issues to see what is currently being worked on. Feel free to add is
# License
Solo is fully open source.
All software is licensed under GPLv3, and hardware under CC BY-SA 4.0.
Software and hardware are available under licenses for commercial use. Please contact SoloKeys for more information.
All software, unless otherwise noted, is dual licensed under Apache 2.0 and MIT.
You may use Solo under the terms of either the Apache 2.0 license or MIT license.
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo?ref=badge_large)

1
STABLE_VERSION Normal file
View File

@ -0,0 +1 @@
1.1.0

0
builds/.gitkeep Normal file
View File

View File

@ -24,12 +24,6 @@ Enter the `stm32l4xx` target directory.
cd targets/stm32l432
```
Build the cbor library.
```bash
make cbor
```
Now build Solo.
```

View File

@ -2,11 +2,11 @@ For information on what this is, see the [spec](https://fidoalliance.org/specs/f
## CTAP2
```
{!metadata/solo-FIDO2-CTAP2-Authenticator.json!}
{!metadata/Solo-FIDO2-CTAP2-Authenticator.json!}
```
## U2F
```
{!metadata/solo-FIDO2-U2F-Authenticator.json!}
{!metadata/Solo-FIDO2-U2F-Authenticator.json!}
```

View File

@ -1,13 +1,16 @@
# tl;dr
Create [`/etc/udev/rules.d/99-solo.rules`](https://github.com/solokeys/solo/blob/master/99-solo.rules) and add the following (which assumes your user is in group `plugdev`):
Create a file like [`/etc/udev/rules.d/99-solo.rules`](https://github.com/solokeys/solo/blob/master/99-solo.rules), for instance the following rules should cover access in all cases:
```
# Solo
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey"
# Solo bootloader + firmware
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev"
# ST DFU bootloader
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", TAG+="uaccess", GROUP="plugdev"
# U2F Zero
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero"
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev"
```
Then run

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _COSE_KEY_H
#define _COSE_KEY_H

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
/*
* Wrapper for crypto implementation on device
*

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _CRYPTO_H
#define _CRYPTO_H

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -36,6 +21,7 @@
#include "device.h"
#include APP_CONFIG
#include "wallet.h"
#include "extensions.h"
#include "device.h"
@ -324,7 +310,7 @@ static int is_matching_rk(CTAP_residentKey * rk, CTAP_residentKey * rk2)
}
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, int len, CTAP_userEntity * user, uint8_t credtype, int32_t algtype, int32_t * sz, int store, bool fromNFC)
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, unsigned int len, CTAP_userEntity * user, uint8_t credtype, int32_t algtype, int32_t * sz, int store, bool fromNFC)
{
CborEncoder cose_key;
int auth_data_sz, ret;
@ -400,8 +386,8 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
memmove(&rk.id, &authData->attest.id, sizeof(CredentialId));
memmove(&rk.user, user, sizeof(CTAP_userEntity));
int index = STATE.rk_stored;
int i;
unsigned int index = STATE.rk_stored;
unsigned int i;
for (i = 0; i < index; i++)
{
ctap_load_rk(i, &rk2);
@ -449,36 +435,46 @@ done_rk:
}
int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder)
/**
*
* @param in_sigbuf IN location to deposit signature (must be 64 bytes)
* @param out_sigder OUT location to deposit der signature (must be 72 bytes)
* @return length of der signature
* // FIXME add tests for maximum and minimum length of the input and output
*/
int ctap_encode_der_sig(const uint8_t * const in_sigbuf, uint8_t * const out_sigder)
{
// Need to caress into dumb der format ..
int i;
int8_t lead_s = 0; // leading zeros
int8_t lead_r = 0;
uint8_t i;
uint8_t lead_s = 0; // leading zeros
uint8_t lead_r = 0;
for (i=0; i < 32; i++)
if (sigbuf[i] == 0) lead_r++;
if (in_sigbuf[i] == 0) lead_r++;
else break;
for (i=0; i < 32; i++)
if (sigbuf[i+32] == 0) lead_s++;
if (in_sigbuf[i+32] == 0) lead_s++;
else break;
int8_t pad_s = ((sigbuf[32 + lead_s] & 0x80) == 0x80);
int8_t pad_r = ((sigbuf[0 + lead_r] & 0x80) == 0x80);
int8_t pad_s = ((in_sigbuf[32 + lead_s] & 0x80) == 0x80);
int8_t pad_r = ((in_sigbuf[0 + lead_r] & 0x80) == 0x80);
sigder[0] = 0x30;
sigder[1] = 0x44 + pad_s + pad_r - lead_s - lead_r;
memset(out_sigder, 0, 72);
out_sigder[0] = 0x30;
out_sigder[1] = 0x44 + pad_s + pad_r - lead_s - lead_r;
sigder[2] = 0x02;
sigder[3 + pad_r] = 0;
sigder[3] = 0x20 + pad_r - lead_r;
memmove(sigder + 4 + pad_r, sigbuf + lead_r, 32);
// R ingredient
out_sigder[2] = 0x02;
out_sigder[3 + pad_r] = 0;
out_sigder[3] = 0x20 + pad_r - lead_r;
memmove(out_sigder + 4 + pad_r, in_sigbuf + lead_r, 32u - lead_r);
// S ingredient
out_sigder[4 + 32 + pad_r - lead_r] = 0x02;
out_sigder[5 + 32 + pad_r + pad_s - lead_r] = 0;
out_sigder[5 + 32 + pad_r - lead_r] = 0x20 + pad_s - lead_s;
memmove(out_sigder + 6 + 32 + pad_r + pad_s - lead_r, in_sigbuf + 32u + lead_s, 32u - lead_s);
sigder[4 + 32 + pad_r - lead_r] = 0x02;
sigder[5 + 32 + pad_r + pad_s - lead_r] = 0;
sigder[5 + 32 + pad_r - lead_r] = 0x20 + pad_s - lead_s;
memmove(sigder + 6 + 32 + pad_r + pad_s - lead_r, sigbuf + 32 + lead_s, 32);
//
return 0x46 + pad_s + pad_r - lead_r - lead_s;
}
@ -486,8 +482,8 @@ int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder)
// @data data to hash before signature
// @clientDataHash for signature
// @tmp buffer for hash. (can be same as data if data >= 32 bytes)
// @sigbuf location to deposit signature (must be 64 bytes)
// @sigder location to deposit der signature (must be 72 bytes)
// @sigbuf OUT location to deposit signature (must be 64 bytes)
// @sigder OUT location to deposit der signature (must be 72 bytes)
// @return length of der signature
int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHash, uint8_t * hashbuf, uint8_t * sigbuf, uint8_t * sigder)
{
@ -559,7 +555,8 @@ int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * d
uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int length, bool fromNFC)
{
CTAP_makeCredential MC;
int ret, i;
int ret;
unsigned int i;
uint8_t auth_data_buf[300];
CTAP_credentialDescriptor * excl_cred = (CTAP_credentialDescriptor *) auth_data_buf;
uint8_t * sigbuf = auth_data_buf + 32;
@ -785,7 +782,18 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
if (! ctap_authenticate_credential(&GA->rp, &GA->creds[i]))
{
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.id.count);
GA->creds[i].credential.id.count = 0; // invalidate
#ifdef ENABLE_U2F_EXTENSIONS
if (is_extension_request((uint8_t*)&GA->creds[i].credential.id, sizeof(CredentialId)))
{
printf1(TAG_EXT, "CRED #%d is extension\n", GA->creds[i].credential.id.count);
count++;
}
else
#endif
{
GA->creds[i].credential.id.count = 0; // invalidate
}
}
else
{
@ -865,6 +873,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
int ret;
uint8_t sigbuf[64];
uint8_t sigder[72];
int sigder_sz;
if (add_user)
{
@ -878,7 +887,16 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
crypto_ecc256_load_key((uint8_t*)&cred->credential.id, sizeof(CredentialId), NULL, 0);
int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
#ifdef ENABLE_U2F_EXTENSIONS
if ( extend_fido2(&cred->credential.id, sigder) )
{
sigder_sz = 72;
}
else
#endif
{
sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
}
{
ret = cbor_encode_int(map, RESP_signature);
@ -997,8 +1015,21 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length,
ret = cbor_encoder_create_map(encoder, &map, map_size);
check_ret(ret);
ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0, fromNFC);
check_retr(ret);
#ifdef ENABLE_U2F_EXTENSIONS
if ( is_extension_request((uint8_t*)&GA.creds[validCredCount - 1].credential.id, sizeof(CredentialId)) )
{
ret = cbor_encode_int(&map,RESP_authData);
check_ret(ret);
memset(auth_data_buf,0,sizeof(auth_data_buf));
ret = cbor_encode_byte_string(&map, auth_data_buf, sizeof(auth_data_buf));
check_ret(ret);
}
else
#endif
{
ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0, fromNFC);
check_retr(ret);
}
/*for (int j = 0; j < GA.credLen; j++)*/
/*{*/
@ -1368,8 +1399,6 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool f
CborEncoder encoder;
uint8_t status = 0;
uint8_t cmd = *pkt_raw;
uint64_t t1;
uint64_t t2;
pkt_raw++;
length--;
@ -1402,10 +1431,9 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool f
case CTAP_MAKE_CREDENTIAL:
device_set_status(CTAPHID_STATUS_PROCESSING);
printf1(TAG_CTAP,"CTAP_MAKE_CREDENTIAL\n");
t1 = millis();
timestamp();
status = ctap_make_credential(&encoder, pkt_raw, length, fromNFC);
t2 = millis();
printf1(TAG_TIME,"make_credential time: %d ms\n", t2-t1);
printf1(TAG_TIME,"make_credential time: %d ms\n", timestamp());
resp->length = cbor_encoder_get_buffer_size(&encoder, buf);
dump_hex1(TAG_DUMP, buf, resp->length);
@ -1414,10 +1442,9 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool f
case CTAP_GET_ASSERTION:
device_set_status(CTAPHID_STATUS_PROCESSING);
printf1(TAG_CTAP,"CTAP_GET_ASSERTION\n");
t1 = millis();
timestamp();
status = ctap_get_assertion(&encoder, pkt_raw, length, fromNFC);
t2 = millis();
printf1(TAG_TIME,"get_assertion time: %d ms\n", t2-t1);
printf1(TAG_TIME,"get_assertion time: %d ms\n", timestamp());
resp->length = cbor_encoder_get_buffer_size(&encoder, buf);

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _CTAP_H
#define _CTAP_H
@ -279,7 +264,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool f
// Encodes R,S signature to 2 der sequence of two integers. Sigder must be at least 72 bytes.
// @return length of der signature
int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder);
int ctap_encode_der_sig(uint8_t const * const in_sigbuf, uint8_t * const out_sigder);
// Run ctap related power-up procedures (init pinToken, generate shared secret)
void ctap_init(int init_pin);

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#define CTAP1_ERR_SUCCESS 0x00
#define CTAP1_ERR_INVALID_COMMAND 0x01
#define CTAP1_ERR_INVALID_PARAMETER 0x02

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include "cbor.h"
@ -94,7 +79,7 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
size_t sz, map_length;
uint8_t key[24];
int ret;
int i;
unsigned int i;
CborValue map;
@ -285,7 +270,7 @@ uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val)
uint8_t cred_type;
int32_t alg_type;
int ret;
int i;
unsigned int i;
CborValue arr;
@ -334,7 +319,7 @@ uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val)
return CTAP2_ERR_UNSUPPORTED_ALGORITHM;
}
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len)
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, unsigned int len)
{
size_t sz;
int ret;
@ -359,7 +344,7 @@ uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len)
uint8_t parse_verify_exclude_list(CborValue * val)
{
int i;
unsigned int i;
int ret;
CborValue arr;
size_t size;
@ -408,7 +393,7 @@ uint8_t parse_rp(struct rpId * rp, CborValue * val)
size_t sz, map_length;
char key[8];
int ret;
int i;
unsigned int i;
CborValue map;
@ -496,7 +481,7 @@ uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up)
size_t sz, map_length;
char key[8];
int ret;
int i;
unsigned int i;
_Bool b;
CborValue map;
@ -574,7 +559,7 @@ uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up)
uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encoder, uint8_t * request, int length)
{
int ret;
int i;
unsigned int i;
int key;
size_t map_length;
CborParser parser;
@ -790,7 +775,8 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
{
CborValue arr;
size_t len;
int i,ret;
int ret;
unsigned int i;
CTAP_credentialDescriptor * cred;
if (cbor_value_get_type(it) != CborArrayType)
@ -832,7 +818,7 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int length)
{
int ret;
int i;
unsigned int i;
int key;
size_t map_length;
CborParser parser;
@ -958,7 +944,8 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
{
CborValue map;
size_t map_length;
int i,ret,key;
int ret,key;
unsigned int i;
int xkey = 0,ykey = 0;
*kty = 0;
*crv = 0;
@ -1053,7 +1040,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
uint8_t ctap_parse_client_pin(CTAP_clientPin * CP, uint8_t * request, int length)
{
int ret;
int i;
unsigned int i;
int key;
size_t map_length;
size_t sz;

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _CTAP_PARSE_H
#define _CTAP_PARSE_H
@ -39,7 +24,7 @@ const char * cbor_value_get_type_string(const CborValue *value);
uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val);
uint8_t parse_pub_key_cred_param(CborValue * val, uint8_t * cred_type, int32_t * alg_type);
uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val);
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len);
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, unsigned int len);
uint8_t parse_rp_id(struct rpId * rp, CborValue * val);
uint8_t parse_rp(struct rpId * rp, CborValue * val);
uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up);

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -113,7 +98,7 @@ static uint32_t get_new_cid()
static int8_t add_cid(uint32_t cid)
{
int i;
uint32_t i;
for(i = 0; i < CID_MAX-1; i++)
{
if (!CIDS[i].busy)
@ -129,7 +114,7 @@ static int8_t add_cid(uint32_t cid)
static int8_t cid_exists(uint32_t cid)
{
int i;
uint32_t i;
for(i = 0; i < CID_MAX-1; i++)
{
if (CIDS[i].cid == cid)
@ -142,7 +127,7 @@ static int8_t cid_exists(uint32_t cid)
static int8_t cid_refresh(uint32_t cid)
{
int i;
uint32_t i;
for(i = 0; i < CID_MAX-1; i++)
{
if (CIDS[i].cid == cid)
@ -157,7 +142,7 @@ static int8_t cid_refresh(uint32_t cid)
static int8_t cid_del(uint32_t cid)
{
int i;
uint32_t i;
for(i = 0; i < CID_MAX-1; i++)
{
if (CIDS[i].cid == cid)
@ -395,7 +380,7 @@ static int ctaphid_buffer_packet(uint8_t * pkt_raw, uint8_t * cmd, uint32_t * ci
printf1(TAG_HID, "Recv packet\n");
printf1(TAG_HID, " CID: %08x \n", pkt->cid);
printf1(TAG_HID, " cmd: %02x\n", pkt->pkt.init.cmd);
if (!is_cont_pkt(pkt)) printf1(TAG_HID, " length: %d\n", ctaphid_packet_len(pkt));
if (!is_cont_pkt(pkt)) {printf1(TAG_HID, " length: %d\n", ctaphid_packet_len(pkt));}
int ret;
uint32_t oldcid;
@ -548,14 +533,14 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
uint8_t cmd;
uint32_t cid;
int len;
#ifndef DISABLE_CTAPHID_CBOR
int status;
#endif
static uint8_t is_busy = 0;
static CTAPHID_WRITE_BUFFER wb;
CTAP_RESPONSE ctap_resp;
uint32_t t1,t2;
int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len);
if (bufstatus == HID_IGNORE)
@ -596,11 +581,11 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
wb.cid = cid;
wb.cmd = CTAPHID_PING;
wb.bcnt = len;
t1 = millis();
timestamp();
ctaphid_write(&wb, ctap_buffer, len);
ctaphid_write(&wb, NULL,0);
t2 = millis();
printf1(TAG_TIME,"PING writeback: %d ms\n",(uint32_t)(t2-t1));
printf1(TAG_TIME,"PING writeback: %d ms\n",timestamp());
break;
#endif
#ifndef DISABLE_CTAPHID_WINK
@ -644,12 +629,11 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
wb.bcnt = (ctap_resp.length+1);
t1 = millis();
timestamp();
ctaphid_write(&wb, &status, 1);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);
t2 = millis();
printf1(TAG_TIME,"CBOR writeback: %d ms\n",(uint32_t)(t2-t1));
printf1(TAG_TIME,"CBOR writeback: %d ms\n",timestamp());
is_busy = 0;
break;
#endif

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _CTAPHID_H_H
#define _CTAPHID_H_H

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _DEVICE_H
#define _DEVICE_H
@ -61,7 +46,7 @@ void device_manage();
// sets status that's uses for sending status updates ~100ms.
// A timer should be set up to call `ctaphid_update_status`
void device_set_status(int status);
void device_set_status(uint32_t status);
// Returns if button is currently pressed
int device_is_button_pressed();

View File

@ -1,28 +1,16 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include "extensions.h"
#include "u2f.h"
#include "ctap.h"
#include "wallet.h"
#include "solo.h"
#include "device.h"
#include "log.h"
@ -69,6 +57,9 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
ret = bootloader_bridge(klen, keyh);
#elif defined(WALLET_EXTENSION)
ret = bridge_u2f_to_wallet(_chal, _appid, klen, keyh);
#else
ret = bridge_u2f_to_solo(sig, keyh, klen);
u2f_response_writeback(sig,72);
#endif
if (ret != 0)
@ -85,6 +76,21 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
return U2F_SW_NO_ERROR;
}
// Returns 1 if this is a extension request.
// Else 0 if nothing is done.
int16_t extend_fido2(CredentialId * credid, uint8_t * output)
{
if (is_extension_request((uint8_t*)credid, sizeof(CredentialId)))
{
output[0] = bridge_u2f_to_solo(output+1, (uint8_t*)credid, sizeof(CredentialId));
return 1;
}
else
{
return 0;
}
}
int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
{
@ -104,7 +110,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
{
rcode = U2F_SW_WRONG_DATA;
}
printf1(TAG_EXT,"Ignoring U2F request\n");
printf1(TAG_EXT,"Ignoring U2F check request\n");
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
goto end;
}
@ -113,7 +119,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
if ( ! is_extension_request((uint8_t *) &auth->kh, auth->khl)) // Pin requests
{
rcode = U2F_SW_WRONG_PAYLOAD;
printf1(TAG_EXT, "Ignoring U2F request\n");
printf1(TAG_EXT, "Ignoring U2F auth request\n");
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
goto end;
}

View File

@ -1,30 +1,19 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef EXTENSIONS_H_
#define EXTENSIONS_H_
#include "u2f.h"
int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len);
int16_t extend_fido2(CredentialId * credid, uint8_t * output);
int bootloader_bridge(int klen, uint8_t * keyh);
int is_extension_request(uint8_t * kh, int len);
#endif /* EXTENSIONS_H_ */

73
fido2/extensions/solo.c Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <stdint.h>
#include "extensions.h"
#include "u2f.h"
#include "wallet.h"
#include "device.h"
#include "ctap.h"
#include "ctap_errors.h"
#include "log.h"
#include APP_CONFIG
// output must be at least 71 bytes
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
{
int8_t ret = 0;
wallet_request * req = (wallet_request *) keyh;
printf1(TAG_WALLET, "u2f-solo [%d]: ", keylen); dump_hex1(TAG_WALLET, keyh, keylen);
switch(req->operation)
{
case WalletVersion:
output[0] = SOLO_VERSION_MAJ;
output[1] = SOLO_VERSION_MIN;
output[2] = SOLO_VERSION_PATCH;
break;
case WalletRng:
printf1(TAG_WALLET,"SoloRng\n");
ret = ctap_generate_rng(output, 71);
if (ret != 1)
{
printf1(TAG_WALLET,"Rng failed\n");
ret = CTAP2_ERR_PROCESSING;
goto cleanup;
}
ret = 0;
break;
default:
printf2(TAG_ERR,"Invalid wallet command: %x\n",req->operation);
ret = CTAP1_ERR_INVALID_COMMAND;
break;
}
cleanup:
return ret;
}

View File

@ -19,13 +19,9 @@
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#ifndef _USB_H
#define _USB_H
#ifndef SOLO_H_
#define SOLO_H_
#include "app_fifo.h"
void usb_init(void);
extern app_fifo_t USBHID_RECV_FIFO;
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen);
#endif

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include "wallet.h"
#include APP_CONFIG
#include "ctap.h"

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef WALLET_H_
#define WALLET_H_

View File

@ -1,29 +1,15 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "log.h"
#include "util.h"
#include "device.h"
#if DEBUG_LEVEL > 0
@ -74,7 +60,7 @@ __attribute__((weak)) void set_logging_tag(uint32_t tag)
void LOG(uint32_t tag, const char * filename, int num, const char * fmt, ...)
{
int i;
unsigned int i;
if (((tag & 0x7fffffff) & LOGMASK) == 0)
{
@ -116,4 +102,14 @@ void LOG_HEX(uint32_t tag, uint8_t * data, int length)
set_logging_tag(tag);
dump_hex(data,length);
}
uint32_t timestamp()
{
static uint32_t t1 = 0;
uint32_t t2 = millis();
uint32_t diff = t2 - t1;
t1 = t2;
return diff;
}
#endif

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _LOG_H
#define _LOG_H
@ -73,13 +58,16 @@ void set_logging_mask(uint32_t mask);
#define dump_hex1(tag,data,len) LOG_HEX(tag,data,len)
uint32_t timestamp();
#else
#define set_logging_mask(mask)
#define printf1(fmt, ...)
#define printf2(fmt, ...)
#define printf3(fmt, ...)
#define printf1(tag,fmt, ...)
#define printf2(tag,fmt, ...)
#define printf3(tag,fmt, ...)
#define dump_hex1(tag,data,len)
#define timestamp()
#endif

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@ -34,7 +19,7 @@
#if !defined(TEST)
int main(int argc, char * argv[])
int main()
{
uint8_t hidmsg[64];
uint32_t t1 = 0;

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _STORAGE_H
#define _STORAGE_H

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include "device.h"
#include "util.h"

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include APP_CONFIG
#ifdef TEST_POWER

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdlib.h>
#include "u2f.h"
#include "ctap.h"
@ -26,12 +11,16 @@
#include "log.h"
#include "device.h"
#include "wallet.h"
#include "apdu.h"
#ifdef ENABLE_U2F_EXTENSIONS
#include "extensions.h"
#endif
#include APP_CONFIG
// void u2f_response_writeback(uint8_t * buf, uint8_t len);
#ifdef ENABLE_U2F
static int16_t u2f_register(struct u2f_register_request * req, bool fromNFC);
static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control, bool fromNFC);
#endif
int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len);
void u2f_reset_response();
@ -41,7 +30,6 @@ static CTAP_RESPONSE * _u2f_resp = NULL;
void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPONSE * resp, bool fromNFC)
{
uint16_t rcode = 0;
uint64_t t1,t2;
uint8_t byte;
ctap_response_init(resp);
@ -56,7 +44,7 @@ void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPO
#ifdef ENABLE_U2F_EXTENSIONS
rcode = extend_u2f(req, len);
#endif
if (rcode != U2F_SW_NO_ERROR) // If the extension didn't do anything...
if (rcode != U2F_SW_NO_ERROR && rcode != U2F_SW_CONDITIONS_NOT_SATISFIED) // If the extension didn't do anything...
{
#ifdef ENABLE_U2F
switch(req->ins)
@ -69,18 +57,18 @@ void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPO
}
else
{
t1 = millis();
rcode = u2f_register((struct u2f_register_request*)payload, fromNFC);
t2 = millis();
printf1(TAG_TIME,"u2f_register time: %d ms\n", t2-t1);
timestamp();
rcode = u2f_register((struct u2f_register_request*)req->payload, fromNFC);
printf1(TAG_TIME,"u2f_register time: %d ms\n", timestamp());
}
break;
case U2F_AUTHENTICATE:
printf1(TAG_U2F, "U2F_AUTHENTICATE\n");
t1 = millis();
rcode = u2f_authenticate((struct u2f_authenticate_request*)payload, req->p1, fromNFC);
t2 = millis();
printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", t2-t1);
timestamp();
rcode = u2f_authenticate((struct u2f_authenticate_request*)req->payload, req->p1, fromNFC);
printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", timestamp());
break;
case U2F_VERSION:
printf1(TAG_U2F, "U2F_VERSION\n");
@ -160,7 +148,8 @@ void u2f_set_writeback_buffer(CTAP_RESPONSE * resp)
_u2f_resp = resp;
}
void dump_signature_der(uint8_t * sig)
#ifdef ENABLE_U2F
static void dump_signature_der(uint8_t * sig)
{
uint8_t sigder[72];
int len;
@ -256,12 +245,10 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
}
count = ctap_atomic_count(0);
uint8_t vcount[4];
vcount[3] = (count) & 0xff;
vcount[2] = (count >> 8) & 0xff;
vcount[1] = (count >> 16) & 0xff;
vcount[0] = (count >> 24) & 0xff;
hash[0] = 0xff;
hash[1] = (count >> 16) & 0xff;
hash[2] = (count >> 8) & 0xff;
hash[3] = (count >> 0) & 0xff;
crypto_sha256_init();
crypto_sha256_update(req->app, 32);
@ -274,8 +261,12 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
printf1(TAG_U2F, "sha256: "); dump_hex1(TAG_U2F, hash, 32);
crypto_ecc256_sign(hash, 32, sig);
u2f_response_writeback(&up, 1);
u2f_response_writeback(vcount, 4);
u2f_response_writeback(&up,1);
hash[0] = 0xff;
hash[1] = (count >> 16) & 0xff;
hash[2] = (count >> 8) & 0xff;
hash[3] = (count >> 0) & 0xff;
u2f_response_writeback(hash,4);
dump_signature_der(sig);
return U2F_SW_NO_ERROR;
@ -340,6 +331,7 @@ static int16_t u2f_register(struct u2f_register_request * req, bool fromNFC)
return U2F_SW_NO_ERROR;
}
#endif
int16_t u2f_version()
{

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _U2F_H_
#define _U2F_H_

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include <stdio.h>

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _UTIL_H
#define _UTIL_H

37
in-docker-build.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/bash -xe
version=${1:-master}
export PREFIX=/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/
cd /solo/targets/stm32l432
git fetch --tags
git checkout ${version}
version=$(git describe)
make cbor
out_dir="/builds"
function build() {
part=${1}
variant=${2}
output=${3:-${part}}
what="${part}-${variant}"
make full-clean
make ${what}
out_hex="${what}-${version}.hex"
out_sha2="${what}-${version}.sha2"
mv ${output}.hex ${out_hex}
sha256sum ${out_hex} > ${out_sha2}
cp ${out_hex} ${out_sha2} ${out_dir}
}
build bootloader nonverifying
build bootloader verifying
build firmware hacker solo
build firmware secure solo

View File

@ -1,24 +1,10 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef SRC_APP_H_
#define SRC_APP_H_

View File

@ -1,24 +1,9 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
@ -41,7 +26,7 @@
void authenticator_initialize();
uint32_t __device_status = 0;
void device_set_status(int status)
void device_set_status(uint32_t status)
{
if (status != CTAPHID_STATUS_IDLE && __device_status != status)
{

File diff suppressed because one or more lines are too long

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EFM32</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>crypto</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/crypto</locationURI>
</link>
<link>
<name>fido2</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/fido2</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,2 +0,0 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -1,70 +0,0 @@
eclipse.preferences.version=1
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.noreturn=Error
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}

View File

@ -1,317 +0,0 @@
/* @file startup_efm32pg1b.S
* @brief startup file for Silicon Labs EFM32PG1B devices.
* For use with GCC for ARM Embedded Processors
* @version 5.2.2
* Date: 12 June 2014
*
*/
/* Copyright (c) 2011 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000C00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long EMU_IRQHandler /* 0 - EMU */
.long Default_Handler /* 1 - Reserved */
.long WDOG0_IRQHandler /* 2 - WDOG0 */
.long Default_Handler /* 3 - Reserved */
.long Default_Handler /* 4 - Reserved */
.long Default_Handler /* 5 - Reserved */
.long Default_Handler /* 6 - Reserved */
.long Default_Handler /* 7 - Reserved */
.long LDMA_IRQHandler /* 8 - LDMA */
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 10 - TIMER0 */
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
.long ACMP0_IRQHandler /* 13 - ACMP0 */
.long ADC0_IRQHandler /* 14 - ADC0 */
.long IDAC0_IRQHandler /* 15 - IDAC0 */
.long I2C0_IRQHandler /* 16 - I2C0 */
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
.long TIMER1_IRQHandler /* 18 - TIMER1 */
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
.long LEUART0_IRQHandler /* 21 - LEUART0 */
.long PCNT0_IRQHandler /* 22 - PCNT0 */
.long CMU_IRQHandler /* 23 - CMU */
.long MSC_IRQHandler /* 24 - MSC */
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long Default_Handler /* 27 - Reserved */
.long Default_Handler /* 28 - Reserved */
.long RTCC_IRQHandler /* 29 - RTCC */
.long Default_Handler /* 30 - Reserved */
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
.long Default_Handler /* 32 - Reserved */
.long FPUEH_IRQHandler /* 33 - FPUEH */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __zero_table_start__ and __zero_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler EMU_IRQHandler
def_irq_handler WDOG0_IRQHandler
def_irq_handler LDMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler IDAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler CRYPTO_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler RTCC_IRQHandler
def_irq_handler CRYOTIMER_IRQHandler
def_irq_handler FPUEH_IRQHandler
.end

View File

@ -1,389 +0,0 @@
/***************************************************************************//**
* @file system_efm32pg1b.c
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
* @version 5.2.2
******************************************************************************
* # License
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
* has no obligation to support this Software. Silicon Laboratories, Inc. is
* providing the Software "AS IS", with no express or implied warranties of any
* kind, including, but not limited to, any implied warranties of
* merchantability or fitness for any particular purpose or warranties against
* infringement of any proprietary rights of a third party.
*
* Silicon Laboratories, Inc. will not be liable for any consequential,
* incidental, or special damages, or any other relief, or for any claim by
* any third party, arising from your use of this Software.
*
*****************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
/** ULFRCO frequency */
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFRCO_MAX_FREQ
/** Maximum HFRCO frequency */
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
#endif
#ifndef EFM32_HFXO_FREQ
/** HFXO frequency */
#define EFM32_HFXO_FREQ (40000000UL)
#endif
#ifndef EFM32_HFRCO_STARTUP_FREQ
/** HFRCO startup frequency */
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
/** LFXO frequency */
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = 32768UL;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
/**
* @brief
* System HFRCO frequency
*
* @note
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
*
* @details
* Frequency of the system HFRCO oscillator
*/
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
uint32_t presc;
ret = SystemHFClockGet();
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
_CMU_HFCOREPRESC_PRESC_SHIFT;
ret /= (presc + 1);
/* Keep CMSIS system clock variable up-to-date */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the maximum core clock frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The maximum core clock frequency in Hz.
******************************************************************************/
uint32_t SystemMaxCoreClockGet(void)
{
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
{
case CMU_HFCLKSTATUS_SELECTED_LFXO:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_HFCLKSTATUS_SELECTED_HFXO:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
ret = SystemHfrcoFreq;
break;
}
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
>> _CMU_HFPRESC_PRESC_SHIFT));
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Set floating point coprosessor access mode. */
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
(3UL << 11*2) ); /* set CP11 Full Access */
#endif
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
<property object="PA0" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA1" propertyId="ports.settings.dout" value="1"/>
<property object="PA1" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA1" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PA1" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA1" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PA3" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA4" propertyId="ports.settings.dout" value="1"/>
<property object="PA4" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA4" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
<property object="PA4" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA4" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PA5" propertyId="ports.settings.dout" value="1"/>
<property object="PA5" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA5" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA5" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA5" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC10" propertyId="ports.settings.dout" value="1"/>
<property object="PC10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC6" propertyId="ports.settings.dout" value="1"/>
<property object="PC6" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC6" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC6" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC6" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC7" propertyId="ports.settings.dout" value="1"/>
<property object="PC7" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC7" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PC7" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC7" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC8" propertyId="ports.settings.dout" value="1"/>
<property object="PC8" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC8" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC8" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC8" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC9" propertyId="ports.settings.dout" value="1"/>
<property object="PC9" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC9" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PC9" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC9" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF2" propertyId="ports.settings.dout" value="1"/>
<property object="PF2" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF2" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF2" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF2" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF3" propertyId="ports.settings.dout" value="1"/>
<property object="PF3" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF3" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
<property object="PF3" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF3" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF4" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF5" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF6" propertyId="ports.settings.dout" value="1"/>
<property object="PF6" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF6" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PF6" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF6" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sclloc" value="3"/>
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sdaloc" value="27"/>
<property object="PORTIO" propertyId="portio.usart0.enable.cts" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rts" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_ctsloc" value="30"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_rtsloc" value="30"/>
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_clkloc" value="11"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="11"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="11"/>
<property object="TIMER0" propertyId="timer.clocksettings.clockselection" value="TIM0_CC1 input"/>
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
<property object="USART1" propertyId="usart.synchronoussettings.clockpolarityphasemode" value="Clock idle low, sample on falling edge"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,107 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32JG1B200F128GM32" partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
<property object="EMU" propertyId="emu.powerconfiguration.externalpowercircuitwiring" value="Not wired for DCDC"/>
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
<property object="PA0" propertyId="ports.settings.pinmode" value="Input"/>
<property object="PA1" propertyId="ports.settings.pinmode" value="Input"/>
<property object="PB11" propertyId="ports.settings.dout" value="1"/>
<property object="PB11" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB11" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB11" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB11" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB12" propertyId="ports.settings.dout" value="1"/>
<property object="PB12" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB12" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PB12" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB12" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB15" propertyId="ports.settings.dout" value="1"/>
<property object="PB15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD11" propertyId="ports.settings.dout" value="1"/>
<property object="PD11" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD11" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PD11" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD11" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD12" propertyId="ports.settings.dout" value="1"/>
<property object="PD12" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD12" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD12" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD12" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD13" propertyId="ports.settings.dout" value="1"/>
<property object="PD13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD13" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PD13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD14" propertyId="ports.settings.dout" value="1"/>
<property object="PD14" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD14" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD14" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD14" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD9" propertyId="ports.settings.dout" value="1"/>
<property object="PD9" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD9" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD9" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD9" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc0" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc1" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc2" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc0loc" value="18"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc1loc" value="16"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc2loc" value="20"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_txloc" value="20"/>
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="6"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="8"/>
<property object="TIMER0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER0" propertyId="timer.capturecomparech0.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech0.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.capturecomparech1.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech1.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.capturecomparech2.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech2.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.clocksettings.hfperprescaler" value="Divide by 512"/>
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
<property object="USART1" propertyId="usart.asynchronoussettings.baudrate" value="130000"/>
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,23 +0,0 @@
CC=arm-none-eabi-gcc
all:
cd 'GNU ARM v7.2.1 - Debug' && make all
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 '-DDEBUG=1' '-DEFM32PG1B200F256GM48=1' -IC:/Users/conor/Desktop/u2f-one/crypto/sha256 -IC:/Users/conor/Desktop/u2f-one/crypto/micro-ecc -IC:/Users/conor/Desktop/u2f-one/crypto/tiny-AES-c -I"C:\Users\conor\Desktop\u2f-one\efm32\inc" -IC:/Users/conor/Desktop/u2f-one/fido2 -IC:/Users/conor/Desktop/u2f-one/tinycbor/src -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/CMSIS/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/drivers" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/SLSTK3401A_EFM32PG/config" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/Device/SiliconLabs/EFM32PG1B/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/emlib/inc" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/bsp" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP -MF"src/device.d" -MT"src/device.o" -o "src/device.o" "../src/device.c"
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "EFM32.ld" -Xlinker --gc-sections -Xlinker -Map="EFM32.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs -o EFM32.axf "./CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.o" "./CMSIS/EFM32PG1B/system_efm32pg1b.o" "./crypto/micro-ecc/uECC.o" "./crypto/sha256/sha256.o" "./crypto/tiny-AES-c/aes.o" "./emlib/em_assert.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_system.o" "./emlib/em_usart.o" "./fido2/crypto.o" "./fido2/ctap.o" "./fido2/ctap_parse.o" "./fido2/ctaphid.o" "./fido2/log.o" "./fido2/main.o" "./fido2/stubs.o" "./fido2/test_power.o" "./fido2/u2f.o" "./fido2/util.o" "./src/InitDevice.o" "./src/device.o" "./src/main.o" "./src/printing.o" "./src/retargetio.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
cbor:
cd ../tinycbor/ && make clean
cd ../tinycbor/ && make CC="$(CC)" \
LDFLAGS="-lgcc -lc -lnosys --specs=nosys.specs -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb " \
CFLAGS="-g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 -DEFM32PG1B200F256GM48=1 -O3 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP "
clean:
cd 'GNU ARM v7.2.1 - Debug' && make clean

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
/***************************************************************************//**
* @file em_assert.c
* @brief Assert API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#include <stdbool.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ASSERT
* @{
******************************************************************************/
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* This implementation simply enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* @note
* This function is not used unless @ref DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @param[in] file
* Name of source file where assertion failed.
*
* @param[in] line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (true) {
}
}
#endif /* DEBUG_EFM */
/** @} (end addtogroup ASSERT) */
/** @} (end addtogroup emlib) */

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/***************************************************************************//**
* @file em_cryotimer.c
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cryotimer.h"
#include "em_bus.h"
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
/***************************************************************************//**
* @brief
* Initialize the CRYOTIMER.
*
* @details
* Use this function to initialize the CRYOTIMER.
* Select prescaler setting and select low frequency oscillator.
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
* details.
*
* @param[in] init
* Pointer to initialization structure.
******************************************************************************/
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
{
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
}
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +0,0 @@
/***************************************************************************//**
* @file em_gpio.c
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @details
* This module contains functions to control the GPIO peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The GPIO peripheral is used for pin configuration
* and direct pin manipulation and sensing as well as routing for peripheral
* pin connections.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
#define GPIO_STRENGHT_VALID(strenght) (!((strenght) \
& ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \
| _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined (_GPIO_ROUTE_SWLOCATION_MASK)
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK)
| (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
#endif
#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
/***************************************************************************//**
* @brief
* Sets the drive strength for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] strength
* Drive strength to use for port.
******************************************************************************/
void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,
GPIO_DriveStrength_TypeDef strength)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));
BUS_RegMaskedWrite(&GPIO->P[port].CTRL,
_GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,
strength);
}
#endif
/***************************************************************************//**
* @brief
* Configure GPIO external pin interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected interrupt is cleared
* by this function.
*
* @note
* On series 0 devices the pin number parameter is not used. The
* pin number used on these devices is hardwired to the interrupt with the
* same number. @n
* On series 1 devices, pin number can be selected freely within a group.
* Interrupt numbers are divided into 4 groups (intNo / 4) and valid pin
* number within the interrupt groups are:
* 0: pins 0-3
* 1: pins 4-7
* 2: pins 8-11
* 3: pins 12-15
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The pin number on the port.
*
* @param[in] intNo
* The interrupt number to trigger.
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
unsigned int intNo,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp = 0;
#if !defined(_GPIO_EXTIPINSELL_MASK)
(void)pin;
#endif
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
#if defined(_GPIO_EXTIPINSELL_MASK)
EFM_ASSERT(GPIO_INTNO_PIN_VALID(intNo, pin));
#endif
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPSELL,
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo),
port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo));
} else {
tmp = intNo - 8;
BUS_RegMaskedWrite(&GPIO->EXTIPSELH,
_GPIO_EXTIPSELH_EXTIPSEL8_MASK
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp),
port << (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#if defined(_GPIO_EXTIPINSELL_MASK)
/* There are two registers controlling the interrupt/pin number mapping:
* The EXTIPINSELL register controls interrupt 0-7 and EXTIPINSELH controls
* interrupt 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELL,
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo),
((pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo));
} else {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELH,
_GPIO_EXTIPINSELH_EXTIPINSEL8_MASK
<< (_GPIO_EXTIPINSELH_EXTIPINSEL9_SHIFT * tmp),
((pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL8_MASK)
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#endif
/* Enable/disable rising edge */
BUS_RegBitWrite(&(GPIO->EXTIRISE), intNo, risingEdge);
/* Enable/disable falling edge */
BUS_RegBitWrite(&(GPIO->EXTIFALL), intNo, fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << intNo;
/* Finally enable/disable interrupt */
BUS_RegBitWrite(&(GPIO->IEN), intNo, enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8) {
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xFu << (pin * 4)))
| (mode << (pin * 4));
} else {
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xFu << ((pin - 8) * 4)))
| (mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
}
/***************************************************************************//**
* @brief
* Get the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @return
* The pin mode.
******************************************************************************/
GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
if (pin < 8) {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEL >> (pin * 4)) & 0xF);
} else {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEH >> ((pin - 8) * 4)) & 0xF);
}
}
#if defined(_GPIO_EM4WUEN_MASK)
/**************************************************************************//**
* @brief
* Enable GPIO pin wake-up from EM4. When the function exits,
* EM4 mode can be safely entered.
*
* @note
* It is assumed that the GPIO pin modes are set correctly.
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
* @param[in] polaritymask
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
#if defined(_GPIO_EM4WUPOL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
GPIO->EM4WUPOL |= pinmask & polaritymask;
#elif defined(_GPIO_EXTILEVEL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);
GPIO->EXTILEVEL &= ~pinmask;
GPIO->EXTILEVEL |= pinmask & polaritymask;
#endif
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
#if defined(_GPIO_CMD_EM4WUCLR_MASK)
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
#elif defined(_GPIO_IFC_EM4WU_MASK)
GPIO_IntClear(pinmask);
#endif
}
#endif
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup emlib) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */

View File

@ -1,811 +0,0 @@
/***************************************************************************//**
* @file em_i2c.c
* @brief Inter-integrated Circuit (I2C) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_i2c.h"
#if defined(I2C_COUNT) && (I2C_COUNT > 0)
#include "em_cmu.h"
#include "em_bus.h"
#include "em_assert.h"
#include <limits.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup I2C
* @brief Inter-integrated Circuit (I2C) Peripheral API
* @details
* This module contains functions to control the I2C peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The I2C interface allows communication on I2C
* buses with the lowest energy consumption possible.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of I2C register block pointer reference for assert statements. */
#if (I2C_COUNT == 1)
#define I2C_REF_VALID(ref) ((ref) == I2C0)
#elif (I2C_COUNT == 2)
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
#elif (I2C_COUNT == 3)
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1) || (ref == I2C2))
#endif
/** Error flags indicating I2C transfer has failed somehow. */
/* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
/* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
/* RXUF is only likely to occur with this SW if using a debugger peeking into */
/* RXDATA register. Thus, we ignore those types of fault. */
#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
/* Max I2C transmission rate constant */
#if defined(_SILICON_LABS_32B_SERIES_0)
#define I2C_CR_MAX 4
#elif defined(_SILICON_LABS_32B_SERIES_1)
#define I2C_CR_MAX 8
#else
#warning "Max I2C transmission rate constant is not defined"
#endif
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Master mode transfer states. */
typedef enum {
i2cStateStartAddrSend, /**< Send start + (first part of) address. */
i2cStateAddrWFAckNack, /**< Wait for ACK/NACK on (first part of) address. */
i2cStateAddrWF2ndAckNack, /**< Wait for ACK/NACK on second part of 10 bit address. */
i2cStateRStartAddrSend, /**< Send repeated start + (first part of) address. */
i2cStateRAddrWFAckNack, /**< Wait for ACK/NACK on address sent after repeated start. */
i2cStateDataSend, /**< Send data. */
i2cStateDataWFAckNack, /**< Wait for ACK/NACK on data sent. */
i2cStateWFData, /**< Wait for data. */
i2cStateWFStopSent, /**< Wait for STOP to have been transmitted. */
i2cStateDone /**< Transfer completed successfully. */
} I2C_TransferState_TypeDef;
/** @endcond */
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Structure used to store state information on an ongoing master mode transfer. */
typedef struct {
/** Current state. */
I2C_TransferState_TypeDef state;
/** Result return code. */
I2C_TransferReturn_TypeDef result;
/** Offset in current sequence buffer. */
uint16_t offset;
/* Index to current sequence buffer in use. */
uint8_t bufIndx;
/** Reference to I2C transfer sequence definition provided by user. */
I2C_TransferSeq_TypeDef *seq;
} I2C_Transfer_TypeDef;
/** @endcond */
/*******************************************************************************
***************************** LOCAL DATA *******^**************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
* index (0x3) to reflect default setting just in case.
*/
static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 6, 4 + 4 };
/** Transfer state info for ongoing master mode transfer */
static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get current configured I2C bus frequency.
*
* @details
* This frequency is only of relevance when acting as master.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Current I2C frequency in Hz.
******************************************************************************/
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
{
uint32_t freqHfper;
uint32_t n;
/* Max frequency is given by freqScl = freqHfper/((Nlow + Nhigh)(DIV + 1) + I2C_CR_MAX)
* More details can be found in the reference manual,
* I2C Clock Generation chapter. */
freqHfper = CMU_ClockFreqGet(cmuClock_HFPER);
/* n = Nlow + Nhigh */
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
return (freqHfper / ((n * (i2c->CLKDIV + 1)) + I2C_CR_MAX));
}
/***************************************************************************//**
* @brief
* Set I2C bus frequency.
*
* @details
* The bus frequency is only of relevance when acting as a master. The bus
* frequency should not be set higher than the max frequency accepted by the
* slowest device on the bus.
*
* Notice that due to asymmetric requirements on low and high I2C clock
* cycles by the I2C specification, the actual max frequency allowed in order
* to comply with the specification may be somewhat lower than expected.
*
* Please refer to the reference manual, details on I2C clock generation,
* for max allowed theoretical frequencies for different modes.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] freqRef
* I2C reference clock frequency in Hz that will be used. If set to 0,
* then HFPER clock is used. Setting it to a higher than actual configured
* value only has the consequence of reducing the real I2C frequency.
*
* @param[in] freqScl
* Bus frequency to set (actual bus speed may be lower due to integer
* prescaling). Safe (according to I2C specification) max frequencies for
* standard, fast and fast+ modes are available using I2C_FREQ_ defines.
* (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
* Slowest slave device on bus must always be considered.
*
* @param[in] i2cMode
* Clock low to high ratio type to use. If not using i2cClockHLRStandard,
* make sure all devices on the bus support the specified mode. Using a
* non-standard ratio is useful to achieve higher bus clock in fast and
* fast+ modes.
******************************************************************************/
void I2C_BusFreqSet(I2C_TypeDef *i2c,
uint32_t freqRef,
uint32_t freqScl,
I2C_ClockHLR_TypeDef i2cMode)
{
uint32_t n, minFreq;
int32_t div;
/* Avoid divide by 0 */
EFM_ASSERT(freqScl);
if (!freqScl) {
return;
}
/* Set the CLHR (clock low to high ratio). */
i2c->CTRL &= ~_I2C_CTRL_CLHR_MASK;
BUS_RegMaskedWrite(&i2c->CTRL,
_I2C_CTRL_CLHR_MASK,
i2cMode << _I2C_CTRL_CLHR_SHIFT);
if (!freqRef) {
freqRef = CMU_ClockFreqGet(cmuClock_HFPER);
}
/* Check minumum HF peripheral clock */
minFreq = UINT_MAX;
if (i2c->CTRL & I2C_CTRL_SLAVE) {
switch (i2cMode) {
case i2cClockHLRStandard:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 4200000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 2000000; break;
#endif
case i2cClockHLRAsymetric:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 11000000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 5000000; break;
#endif
case i2cClockHLRFast:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 24400000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 14000000; break;
#endif
}
} else {
/* For master mode, platform 1 and 2 share the same
min frequencies */
switch (i2cMode) {
case i2cClockHLRStandard:
minFreq = 2000000; break;
case i2cClockHLRAsymetric:
minFreq = 9000000; break;
case i2cClockHLRFast:
minFreq = 20000000; break;
}
}
/* Frequency most be larger-than */
EFM_ASSERT(freqRef > minFreq);
/* SCL frequency is given by
* freqScl = freqRef/((Nlow + Nhigh) * (DIV + 1) + I2C_CR_MAX)
*
* Thus
* DIV = ((freqRef - (I2C_CR_MAX * freqScl))/((Nlow + Nhigh) * freqScl)) - 1
*
* More details can be found in the reference manual,
* I2C Clock Generation chapter. */
/* n = Nlow + Nhigh */
n = (uint32_t)(i2cNSum[i2cMode]);
div = ((freqRef - (I2C_CR_MAX * freqScl)) / (n * freqScl)) - 1;
EFM_ASSERT(div >= 0);
EFM_ASSERT((uint32_t)div <= _I2C_CLKDIV_DIV_MASK);
/* Clock divisor must be at least 1 in slave mode according to reference */
/* manual (in which case there is normally no need to set bus frequency). */
if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div) {
div = 1;
}
i2c->CLKDIV = (uint32_t)div;
}
/***************************************************************************//**
* @brief
* Enable/disable I2C.
*
* @note
* After enabling the I2C (from being disabled), the I2C is in BUSY state.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, enable);
}
/***************************************************************************//**
* @brief
* Initialize I2C.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] init
* Pointer to I2C initialization structure.
******************************************************************************/
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
i2c->IEN = 0;
i2c->IFC = _I2C_IFC_MASK;
/* Set SLAVE select mode */
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_SLAVE_SHIFT, init->master ? 0 : 1);
I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, init->enable);
}
/***************************************************************************//**
* @brief
* Reset I2C to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
******************************************************************************/
void I2C_Reset(I2C_TypeDef *i2c)
{
i2c->CTRL = _I2C_CTRL_RESETVALUE;
i2c->CLKDIV = _I2C_CLKDIV_RESETVALUE;
i2c->SADDR = _I2C_SADDR_RESETVALUE;
i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
i2c->IEN = _I2C_IEN_RESETVALUE;
i2c->IFC = _I2C_IFC_MASK;
/* Do not reset route register, setting should be done independently */
}
/***************************************************************************//**
* @brief
* Continue an initiated I2C transfer (single master mode only).
*
* @details
* This function is used repeatedly after a I2C_TransferInit() in order to
* complete a transfer. It may be used in polled mode as the below example
* shows:
* @verbatim
* I2C_TransferReturn_TypeDef ret;
*
* // Do a polled transfer
* ret = I2C_TransferInit(I2C0, seq);
* while (ret == i2cTransferInProgress)
* {
* ret = I2C_Transfer(I2C0);
* }
* @endverbatim
* It may also be used in interrupt driven mode, where this function is invoked
* from the interrupt handler. Notice that if used in interrupt mode, NVIC
* interrupts must be configured and enabled for the I2C bus used. I2C
* peripheral specific interrupts are managed by this SW.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Returns status for ongoing transfer.
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li #i2cTransferDone - transfer completed successfully.
* @li otherwise some sort of error has occurred.
*
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
{
uint32_t tmp;
uint32_t pending;
I2C_Transfer_TypeDef *transfer;
I2C_TransferSeq_TypeDef *seq;
EFM_ASSERT(I2C_REF_VALID(i2c));
/* Support up to 2 I2C buses */
if (i2c == I2C0) {
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1) {
transfer = i2cTransfer + 1;
}
#endif
#if (I2C_COUNT > 2)
else if (i2c == I2C2) {
transfer = i2cTransfer + 2;
}
#endif
else {
return i2cTransferUsageFault;
}
seq = transfer->seq;
for (;; ) {
pending = i2c->IF;
/* If some sort of fault, abort transfer. */
if (pending & I2C_IF_ERRORS) {
if (pending & I2C_IF_ARBLOST) {
/* If arbitration fault, it indicates either a slave device */
/* not responding as expected, or other master which is not */
/* supported by this SW. */
transfer->result = i2cTransferArbLost;
} else if (pending & I2C_IF_BUSERR) {
/* A bus error indicates a misplaced start or stop, which should */
/* not occur in master mode controlled by this SW. */
transfer->result = i2cTransferBusErr;
}
/* If error situation occurred, it is difficult to know */
/* exact cause and how to resolve. It will be up to a wrapper */
/* to determine how to handle a fault/recovery if possible. */
transfer->state = i2cStateDone;
goto done;
}
switch (transfer->state) {
/***************************************************/
/* Send first start+address (first byte if 10 bit) */
/***************************************************/
case i2cStateStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
/* In 10 bit address mode, the address following the first */
/* start always indicate write. */
} else {
tmp = (uint32_t)(seq->addr) & 0xfe;
if (seq->flags & I2C_FLAG_READ) {
/* Indicate read request */
tmp |= 1;
}
}
transfer->state = i2cStateAddrWFAckNack;
i2c->TXDATA = tmp;/* Data not transmitted until START sent */
i2c->CMD = I2C_CMD_START;
goto done;
/*******************************************************/
/* Wait for ACK/NACK on address (first byte if 10 bit) */
/*******************************************************/
case i2cStateAddrWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* If 10 bit address, send 2nd byte of address. */
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
transfer->state = i2cStateAddrWF2ndAckNack;
i2c->TXDATA = (uint32_t)(seq->addr) & 0xff;
} else {
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_READ) {
transfer->state = i2cStateWFData;
if (seq->buf[transfer->bufIndx].len == 1) {
i2c->CMD = I2C_CMD_NACK;
}
} else {
transfer->state = i2cStateDataSend;
continue;
}
}
}
goto done;
/******************************************************/
/* Wait for ACK/NACK on second byte of 10 bit address */
/******************************************************/
case i2cStateAddrWF2ndAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* If using plain read sequence with 10 bit address, switch to send */
/* repeated start. */
if (seq->flags & I2C_FLAG_READ) {
transfer->state = i2cStateRStartAddrSend;
}
/* Otherwise expected to write 0 or more bytes */
else {
transfer->state = i2cStateDataSend;
}
continue;
}
goto done;
/*******************************/
/* Send repeated start+address */
/*******************************/
case i2cStateRStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
} else {
tmp = seq->addr & 0xfe;
}
/* If this is a write+read combined sequence, then read is about to start */
if (seq->flags & I2C_FLAG_WRITE_READ) {
/* Indicate read request */
tmp |= 1;
}
transfer->state = i2cStateRAddrWFAckNack;
/* We have to write START cmd first since repeated start, otherwise */
/* data would be sent first. */
i2c->CMD = I2C_CMD_START;
i2c->TXDATA = tmp;
goto done;
/**********************************************************************/
/* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
/**********************************************************************/
case i2cStateRAddrWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_WRITE_READ) {
transfer->state = i2cStateWFData;
} else {
transfer->state = i2cStateDataSend;
continue;
}
}
goto done;
/*****************************/
/* Send a data byte to slave */
/*****************************/
case i2cStateDataSend:
/* Reached end of data buffer? */
if (transfer->offset >= seq->buf[transfer->bufIndx].len) {
/* Move to next message part */
transfer->offset = 0;
transfer->bufIndx++;
/* Send repeated start when switching to read mode on 2nd buffer */
if (seq->flags & I2C_FLAG_WRITE_READ) {
transfer->state = i2cStateRStartAddrSend;
continue;
}
/* Only writing from one buffer, or finished both buffers */
if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1)) {
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
goto done;
}
/* Reprocess in case next buffer is empty */
continue;
}
/* Send byte */
i2c->TXDATA = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
transfer->state = i2cStateDataWFAckNack;
goto done;
/*********************************************************/
/* Wait for ACK/NACK from slave after sending data to it */
/*********************************************************/
case i2cStateDataWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
transfer->state = i2cStateDataSend;
continue;
}
goto done;
/****************************/
/* Wait for data from slave */
/****************************/
case i2cStateWFData:
if (pending & I2C_IF_RXDATAV) {
uint8_t data;
unsigned int rxLen = seq->buf[transfer->bufIndx].len;
/* Must read out data in order to not block further progress */
data = (uint8_t)(i2c->RXDATA);
/* Make sure not storing beyond end of buffer just in case */
if (transfer->offset < rxLen) {
seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
}
/* If we have read all requested data, then the sequence should end */
if (transfer->offset >= rxLen) {
/* If there is only one byte to receive we need to transmit the
NACK now, before the stop. */
if (1 == rxLen) {
i2c->CMD = I2C_CMD_NACK;
}
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else {
/* Send ACK and wait for next byte */
i2c->CMD = I2C_CMD_ACK;
if ( (1 < rxLen) && (transfer->offset == (rxLen - 1)) ) {
/* If there is more than one byte to receive and this is the next
to last byte we need to transmit the NACK now, before receiving
the last byte. */
i2c->CMD = I2C_CMD_NACK;
}
}
}
goto done;
/***********************************/
/* Wait for STOP to have been sent */
/***********************************/
case i2cStateWFStopSent:
if (pending & I2C_IF_MSTOP) {
i2c->IFC = I2C_IFC_MSTOP;
transfer->state = i2cStateDone;
}
goto done;
/******************************/
/* Unexpected state, SW fault */
/******************************/
default:
transfer->result = i2cTransferSwFault;
transfer->state = i2cStateDone;
goto done;
}
}
done:
if (transfer->state == i2cStateDone) {
/* Disable interrupt sources when done */
i2c->IEN = 0;
/* Update result unless some fault already occurred */
if (transfer->result == i2cTransferInProgress) {
transfer->result = i2cTransferDone;
}
}
/* Until transfer is done keep returning i2cTransferInProgress */
else {
return i2cTransferInProgress;
}
return transfer->result;
}
/***************************************************************************//**
* @brief
* Prepare and start an I2C transfer (single master mode only).
*
* @details
* This function must be invoked in order to start an I2C transfer
* sequence. In order to actually complete the transfer, I2C_Transfer() must
* be used either in polled mode or by adding a small driver wrapper utilizing
* interrupts.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] seq
* Pointer to sequence structure defining the I2C transfer to take place. The
* referenced structure must exist until the transfer has fully completed.
*
* @return
* Returns status for ongoing transfer:
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li otherwise some sort of error has occurred.
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
I2C_TransferSeq_TypeDef *seq)
{
I2C_Transfer_TypeDef *transfer;
EFM_ASSERT(I2C_REF_VALID(i2c));
EFM_ASSERT(seq);
/* Support up to 2 I2C buses */
if (i2c == I2C0) {
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1) {
transfer = i2cTransfer + 1;
}
#endif
#if (I2C_COUNT > 2)
else if (i2c == I2C2) {
transfer = i2cTransfer + 2;
}
#endif
else {
return i2cTransferUsageFault;
}
/* Check if in busy state. Since this SW assumes single master, we can */
/* just issue an abort. The BUSY state is normal after a reset. */
if (i2c->STATE & I2C_STATE_BUSY) {
i2c->CMD = I2C_CMD_ABORT;
}
/* Make sure user is not trying to read 0 bytes, it is not */
/* possible according to I2C spec, since slave will always start */
/* sending first byte ACK on address. The read operation can */
/* only be stopped by NACKing a received byte, ie minimum 1 byte. */
if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len))
|| ((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
) {
return i2cTransferUsageFault;
}
/* Prepare for a transfer */
transfer->state = i2cStateStartAddrSend;
transfer->result = i2cTransferInProgress;
transfer->offset = 0;
transfer->bufIndx = 0;
transfer->seq = seq;
/* Ensure buffers are empty */
i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
if (i2c->IF & I2C_IF_RXDATAV) {
(void)i2c->RXDATA;
}
/* Clear all pending interrupts prior to starting transfer. */
i2c->IFC = _I2C_IFC_MASK;
/* Enable those interrupts we are interested in throughout transfer. */
/* Notice that the I2C interrupt must also be enabled in the NVIC, but */
/* that is left for an additional driver wrapper. */
i2c->IEN |= I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP
| I2C_IF_RXDATAV | I2C_IF_ERRORS;
/* Start transfer */
return I2C_Transfer(i2c);
}
/** @} (end addtogroup I2C) */
/** @} (end addtogroup emlib) */
#endif /* defined(I2C_COUNT) && (I2C_COUNT > 0) */

View File

@ -1,355 +0,0 @@
/***************************************************************************//**
* @file em_ldma.c
* @brief Direct memory access (LDMA) module peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_ldma.h"
#if defined(LDMA_PRESENT) && (LDMA_COUNT == 1)
#include <stddef.h>
#include "em_assert.h"
#include "em_bus.h"
#include "em_cmu.h"
#include "em_core.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LDMA
* @{
******************************************************************************/
#if defined(LDMA_IRQ_HANDLER_TEMPLATE)
/***************************************************************************//**
* @brief
* Template for an LDMA IRQ handler.
******************************************************************************/
void LDMA_IRQHandler(void)
{
uint32_t ch;
/* Get all pending and enabled interrupts. */
uint32_t pending = LDMA_IntGetEnabled();
/* Loop here on an LDMA error to enable debugging. */
while (pending & LDMA_IF_ERROR) {
}
/* Iterate over all LDMA channels. */
for (ch = 0; ch < DMA_CHAN_COUNT; ch++) {
uint32_t mask = 0x1 << ch;
if (pending & mask) {
/* Clear interrupt flag. */
LDMA->IFC = mask;
/* Do more stuff here, execute callbacks etc. */
}
}
}
#endif
/***************************************************************************//**
* @brief
* De-initialize the LDMA controller.
*
* LDMA interrupts are disabled and the LDMA clock is stopped.
******************************************************************************/
void LDMA_DeInit(void)
{
NVIC_DisableIRQ(LDMA_IRQn);
LDMA->IEN = 0;
LDMA->CHEN = 0;
CMU_ClockEnable(cmuClock_LDMA, false);
}
/***************************************************************************//**
* @brief
* Enable or disable a LDMA channel request.
*
* @details
* Use this function to enable or disable a LDMA channel request. This will
* prevent the LDMA from proceeding after its current transaction if disabled.
*
* @param[in] channel
* LDMA channel to enable or disable requests on.
*
* @param[in] enable
* If 'true' request will be enabled. If 'false' request will be disabled.
******************************************************************************/
void LDMA_EnableChannelRequest(int ch, bool enable)
{
EFM_ASSERT(ch < DMA_CHAN_COUNT);
BUS_RegBitWrite(&LDMA->REQDIS, ch, !enable);
}
/***************************************************************************//**
* @brief
* Initialize the LDMA controller.
*
* @details
* This function will disable all the LDMA channels and enable the LDMA bus
* clock in the CMU. This function will also enable the LDMA IRQ in the NVIC
* and set the LDMA IRQ priority to a user configurable priority. The LDMA
* interrupt priority is configured using the @ref LDMA_Init_t structure.
*
* @note
* Since this function enables the LDMA IRQ you should always add a custom
* LDMA_IRQHandler to the application in order to handle any interrupts
* from LDMA.
*
* @param[in] init
* Pointer to initialization structure used to configure the LDMA.
******************************************************************************/
void LDMA_Init(const LDMA_Init_t *init)
{
EFM_ASSERT(init != NULL);
EFM_ASSERT(!((init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
& ~_LDMA_CTRL_NUMFIXED_MASK));
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(init->ldmaInitIrqPriority < (1 << __NVIC_PRIO_BITS));
CMU_ClockEnable(cmuClock_LDMA, true);
LDMA->CTRL = (init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
| (init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
| (init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
LDMA->CHEN = 0;
LDMA->DBGHALT = 0;
LDMA->REQDIS = 0;
/* Enable LDMA error interrupt. */
LDMA->IEN = LDMA_IEN_ERROR;
LDMA->IFC = 0xFFFFFFFF;
NVIC_ClearPendingIRQ(LDMA_IRQn);
/* Range is 0..7, 0 is highest priority. */
NVIC_SetPriority(LDMA_IRQn, init->ldmaInitIrqPriority);
NVIC_EnableIRQ(LDMA_IRQn);
}
/***************************************************************************//**
* @brief
* Start a DMA transfer.
*
* @param[in] ch
* DMA channel.
*
* @param[in] transfer
* Initialization structure used to configure the transfer.
*
* @param[in] descriptor
* Transfer descriptor, can be an array of descriptors linked together.
******************************************************************************/
void LDMA_StartTransfer(int ch,
const LDMA_TransferCfg_t *transfer,
const LDMA_Descriptor_t *descriptor)
{
uint32_t tmp;
CORE_DECLARE_IRQ_STATE;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
EFM_ASSERT(transfer != NULL);
EFM_ASSERT(!(transfer->ldmaReqSel & ~_LDMA_CH_REQSEL_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(!((transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
& ~_LDMA_CH_CFG_ARBSLOTS_MASK));
EFM_ASSERT(!((transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
& ~_LDMA_CH_CFG_SRCINCSIGN_MASK) );
EFM_ASSERT(!((transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT)
& ~_LDMA_CH_CFG_DSTINCSIGN_MASK));
EFM_ASSERT(!((transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT)
& ~_LDMA_CH_LOOP_LOOPCNT_MASK));
LDMA->CH[ch].REQSEL = transfer->ldmaReqSel;
LDMA->CH[ch].LOOP = (transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT);
LDMA->CH[ch].CFG = (transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
| (transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
| (transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT);
/* Set descriptor address. */
LDMA->CH[ch].LINK = (uint32_t)descriptor & _LDMA_CH_LINK_LINKADDR_MASK;
/* Clear pending channel interrupt. */
LDMA->IFC = chMask;
/* Critical region. */
CORE_ENTER_ATOMIC();
/* Enable channel interrupt. */
LDMA->IEN |= chMask;
if (transfer->ldmaReqDis) {
LDMA->REQDIS |= chMask;
}
if (transfer->ldmaDbgHalt) {
LDMA->DBGHALT |= chMask;
}
tmp = LDMA->CTRL;
if (transfer->ldmaCtrlSyncPrsClrOff) {
tmp &= ~_LDMA_CTRL_SYNCPRSCLREN_MASK
| (~transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT);
}
if (transfer->ldmaCtrlSyncPrsClrOn) {
tmp |= transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT;
}
if (transfer->ldmaCtrlSyncPrsSetOff) {
tmp &= ~_LDMA_CTRL_SYNCPRSSETEN_MASK
| (~transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
}
if (transfer->ldmaCtrlSyncPrsSetOn) {
tmp |= transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT;
}
LDMA->CTRL = tmp;
BUS_RegMaskedClear(&LDMA->CHDONE, chMask); /* Clear the done flag. */
LDMA->LINKLOAD = chMask; /* Start transfer by loading descriptor. */
/* Critical region end. */
CORE_EXIT_ATOMIC();
}
/***************************************************************************//**
* @brief
* Stop a DMA transfer.
*
* @note
* The DMA will complete the current AHB burst transfer before stopping.
*
* @param[in] ch
* DMA channel to stop.
******************************************************************************/
void LDMA_StopTransfer(int ch)
{
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
LDMA->IEN &= ~chMask;
BUS_RegMaskedClear(&LDMA->CHEN, chMask);
)
}
/***************************************************************************//**
* @brief
* Check if a DMA transfer has completed.
*
* @param[in] ch
* DMA channel to check.
*
* @return
* True if transfer has completed, false if not.
******************************************************************************/
bool LDMA_TransferDone(int ch)
{
bool retVal = false;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
if (((LDMA->CHEN & chMask) == 0)
&& ((LDMA->CHDONE & chMask) == chMask)) {
retVal = true;
}
)
return retVal;
}
/***************************************************************************//**
* @brief
* Get number of items remaining in a transfer.
*
* @note
* This function is does not take into account that a DMA transfers with
* a chain of linked transfers might be ongoing. It will only check the
* count for the current transfer.
*
* @param[in] ch
* The channel number of the transfer to check.
*
* @return
* Number of items remaining in the transfer.
******************************************************************************/
uint32_t LDMA_TransferRemainingCount(int ch)
{
uint32_t remaining, done, iflag;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
iflag = LDMA->IF;
done = LDMA->CHDONE;
remaining = LDMA->CH[ch].CTRL;
)
iflag &= chMask;
done &= chMask;
remaining = (remaining & _LDMA_CH_CTRL_XFERCNT_MASK)
>> _LDMA_CH_CTRL_XFERCNT_SHIFT;
if (done || ((remaining == 0) && iflag)) {
return 0;
}
return remaining + 1;
}
/** @} (end addtogroup LDMA) */
/** @} (end addtogroup emlib) */
#endif /* defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 ) */

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/***************************************************************************//**
* @file em_system.c
* @brief System Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
#include <stddef.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
/* CHIP FAMILY bit [5:2] */
tmp = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);
/* CHIP FAMILY bit [1:0] */
tmp |= ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);
rev->family = tmp;
/* CHIP MAJOR bit [3:0] */
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
/* CHIP MINOR bit [7:4] */
tmp = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
/* CHIP MINOR bit [3:0] */
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Peripheral calibration register address to get calibration value for. If
* a calibration value is found then this register is updated with the
* calibration value.
*
* @return
* True if a calibration value exists, false otherwise.
******************************************************************************/
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
SYSTEM_CalAddrVal_TypeDef * p, * end;
p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000);
end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE;
for (; p < end; p++) {
if (p->address == 0xFFFFFFFF) {
/* Found table terminator */
return false;
}
if (p->address == (uint32_t)regAddress) {
*regAddress = p->calValue;
return true;
}
}
/* Nothing found for regAddress */
return false;
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup emlib) */

View File

@ -1,253 +0,0 @@
/***************************************************************************//**
* @file em_timer.c
* @brief Timer/counter (TIMER) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_timer.h"
#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @brief Timer/Counter (TIMER) Peripheral API
* @details
* The timer module consists of three main parts:
* @li General timer config and enable control.
* @li Compare/capture control.
* @li Dead time insertion control (may not be available for all timers).
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize TIMER.
*
* @details
* Notice that counter top must be configured separately with for instance
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
* init must be initialized separately if used. That should probably
* be done prior to the use of this function if configuring the TIMER to
* start when initialization is completed.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
if (!(init->enable)) {
timer->CMD = TIMER_CMD_STOP;
}
/* Reset counter */
timer->CNT = _TIMER_CNT_RESETVALUE;
timer->CTRL = ((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT)
| ((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT)
| ((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT)
| ((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT)
| (init->debugRun ? TIMER_CTRL_DEBUGRUN : 0)
| (init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0)
| (init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0)
| (init->oneShot ? TIMER_CTRL_OSMEN : 0)
#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
| (init->count2x ? TIMER_CTRL_X2CNT : 0)
| (init->ati ? TIMER_CTRL_ATI : 0)
#endif
| (init->sync ? TIMER_CTRL_SYNC : 0);
/* Start timer if specified to be enabled (dosn't hurt if already started) */
if (init->enable) {
timer->CMD = TIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER compare/capture channel.
*
* @details
* Notice that if operating channel in compare mode, the CCV and CCVB register
* must be set separately as required.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to init for.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
EFM_ASSERT(TIMER_CH_VALID(ch));
timer->CC[ch].CTRL =
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT)
| ((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT)
| ((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT)
| ((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT)
| ((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT)
| ((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT)
| (init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0)
| (init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0)
| (init->coist ? TIMER_CC_CTRL_COIST : 0)
| (init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
}
#if defined(_TIMER_DTCTRL_MASK)
/***************************************************************************//**
* @brief
* Initialize the TIMER DTI unit.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER DTI initialization structure.
******************************************************************************/
void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init)
{
EFM_ASSERT(TIMER0 == timer);
/* Make sure the DTI unit is disabled while initializing. */
TIMER_EnableDTI(timer, false);
/* Setup the DTCTRL register.
The enable bit will be set at the end of the function if specified. */
timer->DTCTRL =
(init->autoRestart ? TIMER_DTCTRL_DTDAS : 0)
| (init->activeLowOut ? TIMER_DTCTRL_DTIPOL : 0)
| (init->invertComplementaryOut ? TIMER_DTCTRL_DTCINV : 0)
| (init->enablePrsSource ? TIMER_DTCTRL_DTPRSEN : 0)
| ((uint32_t)(init->prsSel) << _TIMER_DTCTRL_DTPRSSEL_SHIFT);
/* Setup the DTTIME register. */
timer->DTTIME =
((uint32_t)(init->prescale) << _TIMER_DTTIME_DTPRESC_SHIFT)
| ((uint32_t)(init->riseTime) << _TIMER_DTTIME_DTRISET_SHIFT)
| ((uint32_t)(init->fallTime) << _TIMER_DTTIME_DTFALLT_SHIFT);
/* Setup the DTFC register. */
timer->DTFC =
(init->enableFaultSourceCoreLockup ? TIMER_DTFC_DTLOCKUPFEN : 0)
| (init->enableFaultSourceDebugger ? TIMER_DTFC_DTDBGFEN : 0)
| (init->enableFaultSourcePrsSel0 ? TIMER_DTFC_DTPRS0FEN : 0)
| (init->enableFaultSourcePrsSel1 ? TIMER_DTFC_DTPRS1FEN : 0)
| ((uint32_t)(init->faultAction) << _TIMER_DTFC_DTFA_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel0) << _TIMER_DTFC_DTPRS0FSEL_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel1) << _TIMER_DTFC_DTPRS1FSEL_SHIFT);
/* Setup the DTOGEN register. */
timer->DTOGEN = init->outputsEnableMask;
/* Clear any previous DTI faults. */
TIMER_ClearDTIFault(timer, TIMER_GetDTIFault(timer));
/* Enable/disable before returning. */
TIMER_EnableDTI(timer, init->enable);
}
#endif
/***************************************************************************//**
* @brief
* Reset TIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Reset(TIMER_TypeDef *timer)
{
int i;
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Make sure disabled first, before resetting other registers */
timer->CMD = TIMER_CMD_STOP;
timer->CTRL = _TIMER_CTRL_RESETVALUE;
timer->IEN = _TIMER_IEN_RESETVALUE;
timer->IFC = _TIMER_IFC_MASK;
timer->TOPB = _TIMER_TOPB_RESETVALUE;
/* Write TOP after TOPB to invalidate TOPB (clear TIMER_STATUS_TOPBV) */
timer->TOP = _TIMER_TOP_RESETVALUE;
timer->CNT = _TIMER_CNT_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* (Note: ROUTE register may be locked by DTLOCK register.) */
for (i = 0; TIMER_CH_VALID(i); i++) {
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
}
/* Reset dead time insertion module, no effect on timers without DTI */
#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
/* Unlock DTI registers first in case locked */
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
timer->DTFC = _TIMER_DTFC_RESETVALUE;
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
#endif
}
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup emlib) */
#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
//=========================================================
// inc/InitDevice.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
#ifndef __INIT_DEVICE_H__
#define __INIT_DEVICE_H__
// USER CONSTANTS
// USER PROTOTYPES
// $[Mode Transition Prototypes]
extern void enter_DefaultMode_from_RESET(void);
// [Mode Transition Prototypes]$
// $[Config(Per-Module Mode)Transition Prototypes]
extern void EMU_enter_DefaultMode_from_RESET(void);
extern void LFXO_enter_DefaultMode_from_RESET(void);
extern void CMU_enter_DefaultMode_from_RESET(void);
extern void ADC0_enter_DefaultMode_from_RESET(void);
extern void ACMP0_enter_DefaultMode_from_RESET(void);
extern void ACMP1_enter_DefaultMode_from_RESET(void);
extern void IDAC0_enter_DefaultMode_from_RESET(void);
extern void RTCC_enter_DefaultMode_from_RESET(void);
extern void USART0_enter_DefaultMode_from_RESET(void);
extern void USART1_enter_DefaultMode_from_RESET(void);
extern void LEUART0_enter_DefaultMode_from_RESET(void);
extern void WDOG0_enter_DefaultMode_from_RESET(void);
extern void I2C0_enter_DefaultMode_from_RESET(void);
extern void GPCRC_enter_DefaultMode_from_RESET(void);
extern void LDMA_enter_DefaultMode_from_RESET(void);
extern void TIMER0_enter_DefaultMode_from_RESET(void);
extern void TIMER1_enter_DefaultMode_from_RESET(void);
extern void LETIMER0_enter_DefaultMode_from_RESET(void);
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void);
extern void PCNT0_enter_DefaultMode_from_RESET(void);
extern void PRS_enter_DefaultMode_from_RESET(void);
extern void PORTIO_enter_DefaultMode_from_RESET(void);
// [Config(Per-Module Mode)Transition Prototypes]$
// $[User-defined pin name abstraction]
// [User-defined pin name abstraction]$
#endif

View File

@ -1,56 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* app.h
*
* Created on: Jun 26, 2018
* Author: conor
*/
#ifndef SRC_APP_H_
#define SRC_APP_H_
#define DEBUG_LEVEL 1
//#define PRINTING_USE_VCOM
//#define USING_DEV_BOARD
//#define ENABLE_U2F_EXTENSIONS
#define ENABLE_U2F
//#define DISABLE_CTAPHID_PING
//#define DISABLE_CTAPHID_WINK
//#define DISABLE_CTAPHID_CBOR
void printing_init();
//#define TEST
//#define TEST_POWER
// GPIO assignments
#define NFC_DEV_SS gpioPortF,2
#define LED_INIT_VALUE 0x001000
#endif /* SRC_APP_H_ */

View File

@ -1,278 +0,0 @@
/*
* Configuration for enabling CRYPTO hardware acceleration in all mbedtls
* modules when running on SiliconLabs devices.
*
* Copyright (C) 2016, Silicon Labs, http://www.silabs.com
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @defgroup sl_crypto_config Silicon Labs CRYPTO Hardware Acceleration Configuration
* @addtogroup sl_crypto_config
*
* @brief
* mbed TLS configuration for Silicon Labs CRYPTO hardware acceleration
*
* @details
* mbed TLS configuration is composed of settings in this Silicon Labs specific CRYPTO hardware acceleration file located in mbedtls/configs and the mbed TLS configuration file in mbedtls/include/mbedtls/config.h.
* This configuration can be used as a starting point to evaluate hardware acceleration available on Silicon Labs devices.
*
* @{
*/
#ifndef MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
#define MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
#include "em_device.h"
#if !defined(NO_CRYPTO_ACCELERATION)
/**
* @name SECTION: Silicon Labs Acceleration settings
*
* This section sets Silicon Labs Acceleration settings.
* @{
*/
/**
* \def MBEDTLS_AES_ALT
*
* Enable hardware acceleration for the AES block cipher
*
* Module: sl_crypto/src/crypto_aes.c for devices with CRYPTO
* sl_crypto/src/aes_aes.c for devices with AES
*
* See MBEDTLS_AES_C for more information.
*/
#define MBEDTLS_AES_ALT
#define MBEDTLS_ECP_ALT
/**
* \def MBEDTLS_ECP_INTERNAL_ALT
* \def ECP_SHORTWEIERSTRASS
* \def MBEDTLS_ECP_ADD_MIXED_ALT
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
*
* Enable hardware acceleration for the elliptic curve over GF(p) library.
*
* Module: sl_crypto/src/crypto_ecp.c
* Caller: library/ecp.c
*
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
* MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#endif
/**
* \def MBEDTLS_SHA1_ALT
*
* Enable hardware acceleration for the SHA1 cryptographic hash algorithm.
*
* Module: sl_crypto/src/crypto_sha.c
* Caller: library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509write_crt.c
*
* Requires: MBEDTLS_SHA1_C and (CRYPTO_COUNT > 0)
* See MBEDTLS_SHA1_C for more information.
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_SHA1_ALT
#endif
/**
* \def MBEDTLS_SHA256_ALT
*
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
* hash algorithms.
*
* Module: sl_crypto/src/crypto_sha.c
* Caller: library/entropy.c
* library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
* See MBEDTLS_SHA256_C for more information.
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_SHA256_ALT
#endif
#endif /* #if !defined(NO_CRYPTO_ACCELERATION) */
/**
* \def MBEDTLS_TRNG_C
*
* Enable software support for the True Random Number Generator (TRNG)
* incorporated from Series 1 Configuration 2 devices (EFR32MG12, etc.)
* from Silicon Labs.
*
* TRNG is not supported by software for EFR32XG13 (SDID_89) and
* EFR32XG14 (SDID_95).
*
* Requires TRNG_PRESENT &&
* !(_SILICON_LABS_GECKO_INTERNAL_SDID_89 ||
* _SILICON_LABS_GECKO_INTERNAL_SDID_95)
*/
#if defined(TRNG_PRESENT) && \
!(defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) || \
defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95))
#define MBEDTLS_TRNG_C
#endif
/**
* \def MBEDTLS_ENTROPY_ADC_C
*
* Enable software support for the retrieving entropy data from the ADC
* incorporated on devices from Silicon Labs.
*
* Requires ADC_PRESENT && _ADC_SINGLECTRLX_VREFSEL_VENTROPY
*/
#if defined(ADC_PRESENT) && defined(_ADC_SINGLECTRLX_VREFSEL_VENTROPY)
#define MBEDTLS_ENTROPY_ADC_C
#endif
/**
* \def MBEDTLS_ENTROPY_ADC_INSTANCE
*
* Specify which ADC instance shall be used as entropy source.
*
* Requires MBEDTLS_ENTROPY_ADC_C
*/
#if defined(MBEDTLS_ENTROPY_ADC_C)
#define MBEDTLS_ENTROPY_ADC_INSTANCE (0)
#endif
/**
* \def MBEDTLS_ENTROPY_RAIL_C
*
* Enable software support for the retrieving entropy data from the RAIL
* incorporated on devices from Silicon Labs.
*
* Requires _EFR_DEVICE
*/
#if defined(_EFR_DEVICE)
#define MBEDTLS_ENTROPY_RAIL_C
#endif
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
*
* Use the radio (RAIL) as default hardware entropy source.
*
* Requires MBEDTLS_ENTROPY_RAIL_C && _EFR_DEVICE && !MBEDTLS_TRNG_C
*/
#if defined(MBEDTLS_ENTROPY_RAIL_C) && \
defined(_EFR_DEVICE) && !defined(MBEDTLS_TRNG_C)
#define MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
#endif
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT
*
* Integrate the provided default entropy source into the mbed
* TLS entropy infrastructure.
*
* Requires MBEDTLS_TRNG_C || MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
*/
#if defined(MBEDTLS_TRNG_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL)
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#endif
/* Default ECC configuration for Silicon Labs devices: */
/* ECC curves supported by CRYPTO hardware module: */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
/* Save RAM by adjusting to our exact needs */
#define MBEDTLS_ECP_MAX_BITS 256
#ifndef MBEDTLS_MPI_MAX_SIZE
#define MBEDTLS_MPI_MAX_SIZE 32 // 384 bits is 48 bytes
#endif
/*
Set MBEDTLS_ECP_WINDOW_SIZE to configure
ECC point multiplication window size, see ecp.h:
2 = Save RAM at the expense of speed
3 = Improve speed at the expense of RAM
4 = Optimize speed at the expense of RAM
*/
#define MBEDTLS_ECP_WINDOW_SIZE 3
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
/* Significant speed benefit at the expense of some ROM */
#define MBEDTLS_ECP_NIST_OPTIM
/* Include the default mbed TLS config file */
#include "mbedtls/config.h"
#undef MBEDTLS_TIMING_C
#undef MBEDTLS_FS_IO
#undef MBEDTLS_SHA512_C
#undef MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#undef MBEDTLS_NET_C
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ALT
#define MBEDTLS_MPI_MODULAR_DIVISION_ALT
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
//#define MBEDTLS_ENTROPY_ALT
//#define MBEDTLS_MPI_MUL_MPI_ALT // doesnt seem to be implemented
//#define MBEDTLS_MPI_MUL_INT_ALT // makes no difference or slightly slower
#define MBEDTLS_NO_PLATFORM_ENTROPY
/* Hardware entropy source is not yet supported. Uncomment this macro to
provide your own implementation of an entropy collector. */
//#define MBEDTLS_ENTROPY_HARDWARE_ALT
/* Exclude and/or change default config here. E.g.: */
//#undef MBEDTLS_ECP_DP_SECP384R1_ENABLED
//#undef MBEDTLS_ECP_DP_SECP521R1_ENABLED
//#undef MBEDTLS_ECP_DP_BP384R1_ENABLED
//#undef MBEDTLS_ECP_DP_BP512R1_ENABLED
//#undef MBEDTLS_SHA512_C
#include "mbedtls/check_config.h"
/** @} (end section sl_crypto_config) */
/** @} (end addtogroup sl_crypto_config) */
#endif /* MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H */

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* nfc.h
*
* Created on: Jul 22, 2018
* Author: conor
*/
#ifndef INC_NFC_H_
#define INC_NFC_H_
void nfc_test();
#endif /* INC_NFC_H_ */

View File

@ -1,752 +0,0 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library includes]
#include "em_system.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_device.h"
#include "em_chip.h"
#include "em_assert.h"
#include "em_adc.h"
#include "em_cryotimer.h"
#include "em_crypto.h"
#include "em_gpio.h"
#include "em_timer.h"
#include "em_usart.h"
// [Library includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
CHIP_Init();
EMU_enter_DefaultMode_from_RESET();
CMU_enter_DefaultMode_from_RESET();
ADC0_enter_DefaultMode_from_RESET();
USART0_enter_DefaultMode_from_RESET();
USART1_enter_DefaultMode_from_RESET();
TIMER0_enter_DefaultMode_from_RESET();
CRYOTIMER_enter_DefaultMode_from_RESET();
PORTIO_enter_DefaultMode_from_RESET();
// [Config Calls]$
}
//================================================================================
// EMU_enter_DefaultMode_from_RESET
//================================================================================
extern void EMU_enter_DefaultMode_from_RESET(void) {
// $[EMU Initialization]
/* External power circuit not wired for DCDC; shut down regulator */
EMU_DCDCPowerOff();
/* Initialize EM2/EM3 mode */
EMU_EM23Init_TypeDef em23Init = EMU_EM23INIT_DEFAULT;
em23Init.em23VregFullEn = 0;
EMU_EM23Init(&em23Init);
/* Initialize EM4H/S mode */
EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
em4Init.retainLfrco = 0;
em4Init.retainLfxo = 0;
em4Init.retainUlfrco = 0;
em4Init.em4State = emuEM4Shutoff;
em4Init.pinRetentionMode = emuPinRetentionDisable;
EMU_EM4Init(&em4Init);
// [EMU Initialization]$
}
//================================================================================
// LFXO_enter_DefaultMode_from_RESET
//================================================================================
extern void LFXO_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// CMU_enter_DefaultMode_from_RESET
//================================================================================
extern void CMU_enter_DefaultMode_from_RESET(void) {
// $[High Frequency Clock Setup]
/* Initializing HFXO */
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
CMU_HFXOInit(&hfxoInit);
/* Setting system HFRCO frequency */
CMU_HFRCOFreqSet (cmuHFRCOFreq_38M0Hz);
/* Using HFRCO as high frequency clock, HFCLK */
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
// [High Frequency Clock Setup]$
// $[LE clocks enable]
/* Enable ULFRCO oscillator, and wait for it to be stable */
CMU_OscillatorEnable(cmuOsc_ULFRCO, true, true);
// [LE clocks enable]$
// $[LFACLK Setup]
/* LFACLK is disabled */
// [LFACLK Setup]$
// $[LFBCLK Setup]
/* LFBCLK is disabled */
// [LFBCLK Setup]$
// $[LFECLK Setup]
/* LFECLK is disabled */
// [LFECLK Setup]$
// $[Peripheral Clock enables]
/* Enable clock for HF peripherals */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Enable clock for ADC0 */
CMU_ClockEnable(cmuClock_ADC0, true);
/* Enable clock for CRYOTIMER */
CMU_ClockEnable(cmuClock_CRYOTIMER, true);
/* Enable clock for TIMER0 */
CMU_ClockEnable(cmuClock_TIMER0, true);
/* Enable clock for USART0 */
CMU_ClockEnable(cmuClock_USART0, true);
/* Enable clock for USART1 */
CMU_ClockEnable(cmuClock_USART1, true);
/* Enable clock for GPIO by default */
CMU_ClockEnable(cmuClock_GPIO, true);
// [Peripheral Clock enables]$
// $[Clock output]
/* Disable CLKOUT0 output */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL0_MASK)
| CMU_CTRL_CLKOUTSEL0_DISABLED;
/* Disable CLKOUT1 output */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL1_MASK)
| CMU_CTRL_CLKOUTSEL1_DISABLED;
// [Clock output]$
// $[CMU_IO]
/* Disable CLKOUT0 pin */
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT0PEN;
/* Disable CLKOUT1 pin */
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT1PEN;
// [CMU_IO]$
}
//================================================================================
// ADC0_enter_DefaultMode_from_RESET
//================================================================================
extern void ADC0_enter_DefaultMode_from_RESET(void) {
// $[ADC0_Init]
ADC_Init_TypeDef ADC0_init = ADC_INIT_DEFAULT;
ADC0_init.ovsRateSel = adcOvsRateSel2;
ADC0_init.warmUpMode = adcWarmupNormal;
ADC0_init.timebase = ADC_TimebaseCalc(0);
ADC0_init.prescale = ADC_PrescaleCalc(7000000, 0);
ADC0_init.tailgate = 0;
ADC0_init.em2ClockConfig = adcEm2Disabled;
ADC_Init(ADC0, &ADC0_init);
// [ADC0_Init]$
// $[ADC0_InputConfiguration]
// [ADC0_InputConfiguration]$
}
//================================================================================
// ACMP0_enter_DefaultMode_from_RESET
//================================================================================
extern void ACMP0_enter_DefaultMode_from_RESET(void) {
// $[ACMP0_Init]
// [ACMP0_Init]$
// $[ACMP0_IO]
// [ACMP0_IO]$
}
//================================================================================
// ACMP1_enter_DefaultMode_from_RESET
//================================================================================
extern void ACMP1_enter_DefaultMode_from_RESET(void) {
// $[ACMP1_Init]
// [ACMP1_Init]$
// $[ACMP1_IO]
// [ACMP1_IO]$
}
//================================================================================
// IDAC0_enter_DefaultMode_from_RESET
//================================================================================
extern void IDAC0_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// RTCC_enter_DefaultMode_from_RESET
//================================================================================
extern void RTCC_enter_DefaultMode_from_RESET(void) {
// $[Compare/Capture Channel 0 init]
// [Compare/Capture Channel 0 init]$
// $[Compare/Capture Channel 1 init]
// [Compare/Capture Channel 1 init]$
// $[Compare/Capture Channel 2 init]
// [Compare/Capture Channel 2 init]$
// $[RTCC init]
// [RTCC init]$
}
//================================================================================
// USART0_enter_DefaultMode_from_RESET
//================================================================================
extern void USART0_enter_DefaultMode_from_RESET(void) {
// $[USART_InitAsync]
USART_InitAsync_TypeDef initasync = USART_INITASYNC_DEFAULT;
initasync.enable = usartDisable;
initasync.baudrate = 115200;
initasync.databits = usartDatabits8;
initasync.parity = usartNoParity;
initasync.stopbits = usartStopbits1;
initasync.oversampling = usartOVS16;
#if defined( USART_INPUT_RXPRS ) && defined( USART_CTRL_MVDIS )
initasync.mvdis = 0;
initasync.prsRxEnable = 0;
initasync.prsRxCh = 0;
#endif
USART_InitAsync(USART0, &initasync);
// [USART_InitAsync]$
// $[USART_InitSync]
// [USART_InitSync]$
// $[USART_InitPrsTrigger]
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
initprs.rxTriggerEnable = 0;
initprs.txTriggerEnable = 0;
initprs.prsTriggerChannel = usartPrsTriggerCh0;
USART_InitPrsTrigger(USART0, &initprs);
// [USART_InitPrsTrigger]$
// $[USART_InitIO]
/* Disable CLK pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
| USART_ROUTELOC0_CLKLOC_LOC4;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CLKPEN);
/* Disable CS pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
| USART_ROUTELOC0_CSLOC_LOC3;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
/* Disable CTS pin */
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
| USART_ROUTELOC1_CTSLOC_LOC2;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
/* Disable RTS pin */
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
| USART_ROUTELOC1_RTSLOC_LOC1;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
/* Set up RX pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
| USART_ROUTELOC0_RXLOC_LOC0;
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_RXPEN;
/* Set up TX pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
| USART_ROUTELOC0_TXLOC_LOC20;
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_TXPEN;
// [USART_InitIO]$
// $[USART_Misc]
/* Disable CTS */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSEN);
/* Set CTS active low */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSINV);
/* Set RTS active low */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_RTSINV);
/* Set CS active low */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_CSINV);
/* Set TX active high */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_TXINV);
/* Set RX active high */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_RXINV);
// [USART_Misc]$
// $[USART_Enable]
/* Enable USART if opted by user */
USART_Enable(USART0, usartEnable);
// [USART_Enable]$
}
//================================================================================
// USART1_enter_DefaultMode_from_RESET
//================================================================================
extern void USART1_enter_DefaultMode_from_RESET(void) {
// $[USART_InitAsync]
// [USART_InitAsync]$
// $[USART_InitSync]
USART_InitSync_TypeDef initsync = USART_INITSYNC_DEFAULT;
initsync.enable = usartDisable;
initsync.baudrate = 130000;
initsync.databits = usartDatabits8;
initsync.master = 1;
initsync.msbf = 1;
initsync.clockMode = usartClockMode0;
#if defined( USART_INPUT_RXPRS ) && defined( USART_TRIGCTRL_AUTOTXTEN )
initsync.prsRxEnable = 0;
initsync.prsRxCh = 0;
initsync.autoTx = 0;
#endif
USART_InitSync(USART1, &initsync);
// [USART_InitSync]$
// $[USART_InitPrsTrigger]
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
initprs.rxTriggerEnable = 0;
initprs.txTriggerEnable = 0;
initprs.prsTriggerChannel = usartPrsTriggerCh0;
USART_InitPrsTrigger(USART1, &initprs);
// [USART_InitPrsTrigger]$
// $[USART_InitIO]
/* Set up CLK pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
| USART_ROUTELOC0_CLKLOC_LOC4;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_CLKPEN;
/* Disable CS pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
| USART_ROUTELOC0_CSLOC_LOC3;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
/* Disable CTS pin */
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
| USART_ROUTELOC1_CTSLOC_LOC2;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
/* Disable RTS pin */
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
| USART_ROUTELOC1_RTSLOC_LOC1;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
/* Set up RX pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
| USART_ROUTELOC0_RXLOC_LOC6;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_RXPEN;
/* Set up TX pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
| USART_ROUTELOC0_TXLOC_LOC8;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_TXPEN;
// [USART_InitIO]$
// $[USART_Misc]
/* Disable CTS */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSEN);
/* Set CTS active low */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSINV);
/* Set RTS active low */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_RTSINV);
/* Set CS active low */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_CSINV);
/* Set TX active high */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_TXINV);
/* Set RX active high */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_RXINV);
// [USART_Misc]$
// $[USART_Enable]
/* Enable USART if opted by user */
USART_Enable(USART1, usartEnable);
// [USART_Enable]$
}
//================================================================================
// LEUART0_enter_DefaultMode_from_RESET
//================================================================================
extern void LEUART0_enter_DefaultMode_from_RESET(void) {
// $[LEUART0 initialization]
// [LEUART0 initialization]$
}
//================================================================================
// WDOG0_enter_DefaultMode_from_RESET
//================================================================================
extern void WDOG0_enter_DefaultMode_from_RESET(void) {
// $[WDOG Initialization]
// [WDOG Initialization]$
}
//================================================================================
// I2C0_enter_DefaultMode_from_RESET
//================================================================================
extern void I2C0_enter_DefaultMode_from_RESET(void) {
// $[I2C0 I/O setup]
// [I2C0 I/O setup]$
// $[I2C0 initialization]
// [I2C0 initialization]$
}
//================================================================================
// GPCRC_enter_DefaultMode_from_RESET
//================================================================================
extern void GPCRC_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// LDMA_enter_DefaultMode_from_RESET
//================================================================================
extern void LDMA_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// TIMER0_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER0_enter_DefaultMode_from_RESET(void) {
// $[TIMER0 I/O setup]
/* Set up CC0 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC0LOC_MASK))
| TIMER_ROUTELOC0_CC0LOC_LOC18;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC0PEN;
/* Set up CC1 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC1LOC_MASK))
| TIMER_ROUTELOC0_CC1LOC_LOC16;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC1PEN;
/* Set up CC2 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC2LOC_MASK))
| TIMER_ROUTELOC0_CC2LOC_LOC20;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC2PEN;
/* Set up CDTI0 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI0LOC_MASK))
| TIMER_ROUTELOC2_CDTI0LOC_LOC3;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI0PEN);
/* Set up CDTI1 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI1LOC_MASK))
| TIMER_ROUTELOC2_CDTI1LOC_LOC2;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI1PEN);
/* Set up CDTI2 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI2LOC_MASK))
| TIMER_ROUTELOC2_CDTI2LOC_LOC1;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI2PEN);
// [TIMER0 I/O setup]$
// $[TIMER0 initialization]
TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT;
init.enable = 1;
init.debugRun = 0;
init.dmaClrAct = 0;
init.sync = 0;
init.clkSel = timerClkSelHFPerClk;
init.prescale = timerPrescale512;
init.fallAction = timerInputActionNone;
init.riseAction = timerInputActionNone;
init.mode = timerModeUp;
init.quadModeX4 = 0;
init.oneShot = 0;
init.count2x = 0;
init.ati = 0;
TIMER_Init(TIMER0, &init);
// [TIMER0 initialization]$
// $[TIMER0 CC0 init]
TIMER_InitCC_TypeDef initCC0 = TIMER_INITCC_DEFAULT;
initCC0.prsInput = false;
initCC0.prsSel = timerPRSSELCh0;
initCC0.edge = timerEdgeRising;
initCC0.mode = timerCCModePWM;
initCC0.eventCtrl = timerEventEveryEdge;
initCC0.filter = 0;
initCC0.cofoa = timerOutputActionNone;
initCC0.cufoa = timerOutputActionNone;
initCC0.cmoa = timerOutputActionToggle;
initCC0.coist = 0;
initCC0.outInvert = 0;
TIMER_InitCC(TIMER0, 0, &initCC0);
// [TIMER0 CC0 init]$
// $[TIMER0 CC1 init]
TIMER_InitCC_TypeDef initCC1 = TIMER_INITCC_DEFAULT;
initCC1.prsInput = false;
initCC1.prsSel = timerPRSSELCh0;
initCC1.edge = timerEdgeRising;
initCC1.mode = timerCCModePWM;
initCC1.eventCtrl = timerEventEveryEdge;
initCC1.filter = 0;
initCC1.cofoa = timerOutputActionNone;
initCC1.cufoa = timerOutputActionNone;
initCC1.cmoa = timerOutputActionToggle;
initCC1.coist = 0;
initCC1.outInvert = 0;
TIMER_InitCC(TIMER0, 1, &initCC1);
// [TIMER0 CC1 init]$
// $[TIMER0 CC2 init]
TIMER_InitCC_TypeDef initCC2 = TIMER_INITCC_DEFAULT;
initCC2.prsInput = false;
initCC2.prsSel = timerPRSSELCh0;
initCC2.edge = timerEdgeRising;
initCC2.mode = timerCCModePWM;
initCC2.eventCtrl = timerEventEveryEdge;
initCC2.filter = 0;
initCC2.cofoa = timerOutputActionNone;
initCC2.cufoa = timerOutputActionNone;
initCC2.cmoa = timerOutputActionToggle;
initCC2.coist = 0;
initCC2.outInvert = 0;
TIMER_InitCC(TIMER0, 2, &initCC2);
// [TIMER0 CC2 init]$
// $[TIMER0 DTI init]
TIMER_InitDTI_TypeDef initDTI = TIMER_INITDTI_DEFAULT;
initDTI.enable = 0;
initDTI.activeLowOut = 0;
initDTI.invertComplementaryOut = 0;
initDTI.autoRestart = 0;
initDTI.enablePrsSource = 0;
initDTI.prsSel = timerPRSSELCh0;
initDTI.prescale = timerPrescale1;
initDTI.riseTime = 1;
initDTI.fallTime = 1;
initDTI.enableFaultSourceCoreLockup = 1;
initDTI.enableFaultSourceDebugger = 1;
initDTI.faultSourcePrsSel0 = 0;
initDTI.faultSourcePrsSel0 = timerPRSSELCh0;
initDTI.faultSourcePrsSel1 = 0;
initDTI.faultSourcePrsSel1 = timerPRSSELCh0;
initDTI.faultAction = timerDtiFaultActionInactive;
initDTI.outputsEnableMask = 0 | TIMER_DTOGEN_DTOGCC0EN
| TIMER_DTOGEN_DTOGCC1EN | TIMER_DTOGEN_DTOGCC2EN;
TIMER_InitDTI(TIMER0, &initDTI);
// [TIMER0 DTI init]$
}
//================================================================================
// TIMER1_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER1_enter_DefaultMode_from_RESET(void) {
// $[TIMER1 I/O setup]
// [TIMER1 I/O setup]$
// $[TIMER1 initialization]
// [TIMER1 initialization]$
// $[TIMER1 CC0 init]
// [TIMER1 CC0 init]$
// $[TIMER1 CC1 init]
// [TIMER1 CC1 init]$
// $[TIMER1 CC2 init]
// [TIMER1 CC2 init]$
// $[TIMER1 CC3 init]
// [TIMER1 CC3 init]$
}
//================================================================================
// LETIMER0_enter_DefaultMode_from_RESET
//================================================================================
extern void LETIMER0_enter_DefaultMode_from_RESET(void) {
// $[LETIMER0 Compare Values]
// [LETIMER0 Compare Values]$
// $[LETIMER0 Repeat Values]
// [LETIMER0 Repeat Values]$
// $[LETIMER0 Initialization]
// [LETIMER0 Initialization]$
// $[LETIMER0 PRS Input Triggers]
// [LETIMER0 PRS Input Triggers]$
// $[LETIMER0 I/O setup]
// [LETIMER0 I/O setup]$
}
//================================================================================
// CRYOTIMER_enter_DefaultMode_from_RESET
//================================================================================
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void) {
// $[CRYOTIMER_Init]
CRYOTIMER_Init_TypeDef cryoInit = CRYOTIMER_INIT_DEFAULT;
/* General settings */
cryoInit.enable = 1;
cryoInit.debugRun = 0;
cryoInit.em4Wakeup = 0;
/* Clocking settings */
/* With a frequency of 1000Hz on ULFRCO, this will result in a 1.00 ms timeout */
cryoInit.osc = cryotimerOscULFRCO;
cryoInit.presc = cryotimerPresc_1;
cryoInit.period = cryotimerPeriod_1;
CRYOTIMER_Init(&cryoInit);
// [CRYOTIMER_Init]$
}
//================================================================================
// PCNT0_enter_DefaultMode_from_RESET
//================================================================================
extern void PCNT0_enter_DefaultMode_from_RESET(void) {
// $[PCNT0 I/O setup]
// [PCNT0 I/O setup]$
// $[PCNT0 initialization]
// [PCNT0 initialization]$
}
//================================================================================
// PRS_enter_DefaultMode_from_RESET
//================================================================================
extern void PRS_enter_DefaultMode_from_RESET(void) {
// $[PRS initialization]
// [PRS initialization]$
}
//================================================================================
// PORTIO_enter_DefaultMode_from_RESET
//================================================================================
extern void PORTIO_enter_DefaultMode_from_RESET(void) {
// $[Port A Configuration]
/* Pin PA0 is configured to Input enabled */
GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 0);
/* Pin PA1 is configured to Input enabled */
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0);
// [Port A Configuration]$
// $[Port B Configuration]
/* Pin PB11 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 11, gpioModePushPull, 1);
/* Pin PB12 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortB, 12, gpioModeInputPull, 1);
/* Pin PB13 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 13, gpioModePushPull, 1);
/* Pin PB15 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
// [Port B Configuration]$
// $[Port C Configuration]
// [Port C Configuration]$
// $[Port D Configuration]
/* Pin PD9 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 1);
/* Pin PD10 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 10, gpioModePushPull, 1);
/* Pin PD11 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortD, 11, gpioModeInputPull, 1);
/* Pin PD12 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 12, gpioModePushPull, 1);
/* Pin PD13 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortD, 13, gpioModeInputPull, 1);
/* Pin PD14 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 14, gpioModePushPull, 1);
/* Pin PD15 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 1);
// [Port D Configuration]$
// $[Port E Configuration]
// [Port E Configuration]$
// $[Port F Configuration]
// [Port F Configuration]$
}

View File

@ -1,689 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Wrapper for crypto implementation on device
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "em_adc.h"
#include "util.h"
#include "crypto.h"
#include "device.h"
#include "sha256.h"
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "log.h"
#include MBEDTLS_CONFIG_FILE
#include "sha256_alt.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/ecdsa.h"
const uint8_t attestation_cert_der[];
const uint16_t attestation_cert_der_size;
const uint8_t attestation_key[];
const uint16_t attestation_key_size;
static mbedtls_sha256_context embed_sha256_ctx;
static mbedtls_ctr_drbg_context ctr_drbg;
static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = NULL;
static int _key_len = 0;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
void crypto_sha256_init()
{
mbedtls_sha256_init( &embed_sha256_ctx );
mbedtls_sha256_starts(&embed_sha256_ctx,0);
// sha256_init(&sha256_ctx);
}
void crypto_reset_master_secret()
{
ctap_generate_rng(master_secret, 32);
}
void crypto_sha256_update(uint8_t * data, size_t len)
{
mbedtls_sha256_update(&embed_sha256_ctx,data,len);
// sha256_update(&sha256_ctx, data, len);
}
void crypto_sha256_update_secret()
{
mbedtls_sha256_update(&embed_sha256_ctx,master_secret,32);
// sha256_update(&sha256_ctx, master_secret, 32);
}
void crypto_sha256_final(uint8_t * hash)
{
mbedtls_sha256_finish( &embed_sha256_ctx, hash );
// sha256_final(&sha256_ctx, hash);
}
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x36;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
}
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x5c;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
crypto_sha256_update(hmac, 32);
crypto_sha256_final(hmac);
}
uint8_t adc_rng(void)
{
int i;
uint8_t random = 0;
/* Random number generation */
for (i=0; i<3; i++)
{
ADC_Start(ADC0, adcStartSingle);
while ((ADC0->IF & ADC_IF_SINGLE) == 0);
random |= ((ADC_DataSingleGet(ADC0) & 0x07) << (i * 3));
}
return random;
}
// Generate @num bytes of random numbers to @dest
// return 1 if success, error otherwise
int ctap_generate_rng(uint8_t * dst, size_t num)
{
return mbedtls_ctr_drbg_random(&ctr_drbg,dst,num) == 0;
}
int adc_entropy_func( void *data, unsigned char *output, size_t len )
{
while(len--)
*output++ = adc_rng();
return 0;
}
void crypto_ecc256_init()
{
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
_es256_curve = uECC_secp256r1();
mbedtls_ctr_drbg_init(&ctr_drbg);
if ( mbedtls_ctr_drbg_seed(&ctr_drbg, adc_entropy_func, NULL,
master_secret,32 ) != 0 ) {
printf2(TAG_ERR, "mbedtls_ctr_drbg_seed failed\n");
exit(1);
}
}
void crypto_load_external_key(uint8_t * key, int len)
{
_signing_key = key;
_key_len = len;
}
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
_key_len = 32;
}
/**
* \brief Import a point from unsigned binary data
*
* \param grp Group to which the point should belong
* \param P Point to import
* \param buf Input buffer
* \param ilen Actual length of input
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
* is not implemented.
*
* \note This function does NOT check that the point actually
* belongs to the given group, see mbedtls_ecp_check_pubkey() for
* that.
*/
//int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
// const unsigned char *buf, size_t ilen );
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
//int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
/*
* Set context from an mbedtls_ecp_keypair
*/
//int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
//#define CRYPTO_ENABLE CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_CRYPTO; \
// CRYPTO->IFC = _CRYPTO_IFC_MASK; \
// CRYPTO->CMD = CRYPTO_CMD_SEQSTOP; \
// CRYPTO->CTRL = CRYPTO_CTRL_DMA0RSEL_DDATA0; \
// CRYPTO->SEQCTRL = 0; \
// CRYPTO->SEQCTRLB = 0
//
//#define CRYPTO_DISABLE \
// CRYPTO->IEN = 0; \
// CMU->HFBUSCLKEN0 &= ~CMU_HFBUSCLKEN0_CRYPTO;
// CRYPTO_DISABLE;
// CRYPTO_ENABLE;
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
// mbedtls_mpi_read_binary(&d, _signing_key, 32);
//
// mbedtls_mpi r,s;
// mbedtls_mpi_init(&r);
// mbedtls_mpi_init(&s);
//
// printf("signing..\n");
// dump_hex(data,len);
// mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
// data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
// printf("signed\n");
//
// mbedtls_mpi_write_binary(&r,sig,32);
// mbedtls_mpi_write_binary(&s,sig+32,32);
if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
}
#if 1
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
const struct uECC_Curve_t * curve = NULL;
switch(MBEDTLS_ECP_ID)
{
case MBEDTLS_ECP_DP_SECP192R1:
curve = uECC_secp192r1();
if (_key_len != 24) goto fail;
break;
case MBEDTLS_ECP_DP_SECP224R1:
curve = uECC_secp224r1();
if (_key_len != 28) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256R1:
curve = uECC_secp256r1();
if (_key_len != 32) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256K1:
curve = uECC_secp256k1();
if (_key_len != 32) goto fail;
break;
default:
printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n");
exit(1);
}
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
return;
fail:
printf2(TAG_ERR,"error, invalid key length: %d\n", _key_len);
exit(1);
}
#else
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
mbedtls_ecp_group_init( &grp );
mbedtls_mpi_init( &d );
mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_ID);
mbedtls_mpi_read_binary(&d, _signing_key, 32);
mbedtls_mpi r,s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
printf("signing..\n");
dump_hex(data,len);
mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
printf("signed\n");
mbedtls_mpi_write_binary(&r,sig,32);
mbedtls_mpi_write_binary(&s,sig+32,32);
}
#endif
/*
* Generate a keypair with configurable base point
*/
// mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng )
// mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng )
/*
* Curve types: internal for now, might be exposed later
*/
typedef enum
{
ECP_TYPE_NONE = 0,
ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
} ecp_curve_type;
/*
* Get the type of a curve
*/
static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
{
if( grp->G.X.p == NULL )
return( ECP_TYPE_NONE );
if( grp->G.Y.p == NULL )
return( ECP_TYPE_MONTGOMERY );
else
return( ECP_TYPE_SHORT_WEIERSTRASS );
}
static int mbedtls_ecp_gen_privkey( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
size_t n_size = ( grp->nbits + 7 ) / 8;
#if defined(ECP_MONTGOMERY)
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
{
/* [M225] page 5 */
size_t b;
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
/* Make sure the most significant bit is nbits */
b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
if( b > grp->nbits )
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
else
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
/* Make sure the last three bits are unset */
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
}
else
#endif /* ECP_MONTGOMERY */
#if defined(ECP_SHORTWEIERSTRASS)
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
{
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0;
unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
/*
* Match the procedure given in RFC 6979 (deterministic ECDSA):
* - use the same byte ordering;
* - keep the leftmost nbits bits of the generated octet string;
* - try until result is in the desired range.
* This also avoids any biais, which is especially important for ECDSA.
*/
do
{
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
/*
* Each try has at worst a probability 1/2 of failing (the msb has
* a probability 1/2 of being 0, and then the result will be < N),
* so after 30 tries failure probability is a most 2**(-30).
*
* For most curves, 1 try is enough with overwhelming probability,
* since N starts with a lot of 1s in binary, but some curves
* such as secp224k1 are actually very close to the worst case.
*/
if( ++count > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
}
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
}
else
#endif /* ECP_SHORTWEIERSTRASS */
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
cleanup:
if( ret != 0 )
return( ret );
return 0;
}
static int mbedtls_ecp_derive_pubkey( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
}
static int hmac_vector_func(uint8_t * hmac, uint8_t * dst, int len)
{
static int hmac_ptr = 0;
if (hmac==NULL)
{
hmac_ptr = 0;
return 0;
}
int i;
while(len--)
{
*dst++ = hmac[hmac_ptr++ % 32];
}
return 0;
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
// mbedtls_mpi d; /*!< our secret value */
// mbedtls_ecp_point Q;
//
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_point_init(&Q);
//
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
//
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
// hmac_vector_func(NULL, NULL, 0);
// mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
// mbedtls_mpi_write_binary(&d,privkey,32);
}
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
{
int ret;
uint8_t privkey[32];
uint8_t pubkey[64];
// generate_private_key(data,len,NULL,0,privkey);
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(NULL, 0);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
// mbedtls_mpi d; /*!< our secret value */
// mbedtls_ecp_point Q;
//
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_point_init(&Q);
//
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
//
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
// hmac_vector_func(NULL, NULL, 0);
// ret= mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
// if (ret != 0)
// {
// printf("error with priv key -0x04%x\n", -ret);
// }
//// mbedtls_mpi_write_binary(&d,privkey,32);
//
// memset(pubkey,0,sizeof(pubkey));
//
// ret = mbedtls_ecp_derive_pubkey( &grp, &grp.G,
// &d, &Q, hmac_vector_func, privkey);
//
// if (ret != 0)
// {
// printf("error with public key\n");
// }
//
// mbedtls_mpi_write_binary(&Q.X,x,32);
// mbedtls_mpi_write_binary(&Q.Y,y,32);
uECC_compute_public_key(privkey, pubkey, _es256_curve);
memmove(x,pubkey,32);
memmove(y,pubkey+32,32);
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_key_len = 32;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_make_key failed\n");
exit(1);
}
}
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
{
if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_shared_secret failed\n");
exit(1);
}
}
struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
{
if (key == CRYPTO_TRANSPORT_KEY)
{
AES_init_ctx(&aes_ctx, transport_secret);
}
else
{
AES_init_ctx(&aes_ctx, key);
}
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
// prevent round key recomputation
void crypto_aes256_reset_iv(uint8_t * nonce)
{
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
void crypto_aes256_decrypt(uint8_t * buf, int length)
{
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
}
void crypto_aes256_encrypt(uint8_t * buf, int length)
{
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}
const uint8_t attestation_cert_der[] =
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
const uint16_t attestation_key_size = sizeof(attestation_key)-1;

View File

@ -1,713 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* device.c
*
* Created on: Jun 27, 2018
* Author: conor
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "em_chip.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_adc.h"
#include "em_cmu.h"
#include "em_msc.h"
#include "em_i2c.h"
#include "em_timer.h"
#include "InitDevice.h"
#include "cbor.h"
#include "log.h"
#include "ctaphid.h"
#include "util.h"
#include "app.h"
#include "uECC.h"
#include "crypto.h"
#include "nfc.h"
#ifdef USING_DEV_BOARD
#define MSG_AVAIL_PIN gpioPortC,9
#define RDY_PIN gpioPortC,10
#define RW_PIN gpioPortD,11
#define RESET_PIN gpioPortB,13
#define LED_RED_PIN gpioPortF,4
#define LED_GREEN_PIN gpioPortF,5
#else
#define MSG_AVAIL_PIN gpioPortA,1
#define RDY_PIN gpioPortA,0
#define RW_PIN gpioPortD,15
#define RESET_PIN gpioPortB,15
#define LED_RED_PIN gpioPortD,10
#define LED_GREEN_PIN gpioPortD,14
#define LED_BLUE_PIN gpioPortD,9
#define BUTTON_PIN gpioPortD,13
#define RED_CHANNEL 0
#define GREEN_CHANNEL 2
#define BLUE_CHANNEL 1
#endif
#define PAGE_SIZE 2048
#define PAGES 64
#define COUNTER_PAGE (PAGES - 3)
#define STATE1_PAGE (PAGES - 2)
#define STATE2_PAGE (PAGES - 1)
#define APPLICATION_START_ADDR 0x4000
#define APPLICATION_START_PAGE (0x4000/PAGE_SIZE)
#define APPLICATION_END_ADDR (PAGE_SIZE*(PAGES - 3)-4) // NOT included in application
#define APPLICATION_END_PAGE ((PAGES - 3)) // 125 is NOT included in application
#define AUTH_WORD_ADDR (PAGE_SIZE*(PAGES - 3)-4)
static void init_atomic_counter()
{
int offset = 0;
uint32_t count;
uint32_t one = 1;
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
for (offset = 0; offset < PAGE_SIZE/4; offset += 1)
{
count = *(ptr+offset);
if (count != 0xffffffff)
{
return;
}
}
MSC_WriteWordFast(ptr,&one,4);
}
uint32_t ctap_atomic_count(int sel)
{
int offset = 0;
uint32_t count;
uint32_t zero = 0;
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
if (sel != 0)
{
printf2(TAG_ERR,"counter2 not imple\n");
exit(1);
}
for (offset = 0; offset < PAGE_SIZE/4; offset += 1) // wear-level the flash
{
count = *(ptr+offset);
if (count != 0)
{
count++;
offset++;
if (offset == PAGE_SIZE/4)
{
offset = 0;
MSC_ErasePage(ptr);
/*printf("RESET page counter\n");*/
}
else
{
MSC_WriteWordFast(ptr+offset-1,&zero,4);
}
MSC_WriteWordFast(ptr+offset,&count,4);
break;
}
}
return count;
}
static uint32_t _color;
uint32_t get_RBG()
{
return _color;
}
void RGB(uint32_t hex)
{
uint16_t r = 256 - ((hex & 0xff0000) >> 16);
uint16_t g = 256 - ((hex & 0xff00) >> 8);
uint16_t b = 256 - ((hex & 0xff) >> 0);
TIMER_CompareBufSet(TIMER0, GREEN_CHANNEL, g); // green
TIMER_CompareBufSet(TIMER0, RED_CHANNEL, r); // red
TIMER_CompareBufSet(TIMER0, BLUE_CHANNEL, b); // blue
_color = hex;
}
#define IS_BUTTON_PRESSED() (GPIO_PinInGet(BUTTON_PIN) == 0)
// Verify the user
// return 1 if user is verified, 0 if not
int ctap_user_verification(uint8_t arg)
{
return 1;
}
// Test for user presence
// Return 1 for user is present, 0 user not present
int ctap_user_presence_test()
{
#ifdef SKIP_BUTTON_CHECK
return 1;
#endif
uint32_t t1 = millis();
RGB(0x304010);
#ifdef USE_BUTTON_DELAY
delay(3000);
RGB(0x001040);
delay(50);
return 1;
#endif
while (IS_BUTTON_PRESSED())
{
if (t1 + 5000 < millis())
{
printf1(TAG_GEN,"Button not pressed\n");
return 0;
}
}
t1 = millis();
do
{
if (t1 + 5000 < millis())
{
return 0;
}
if (! IS_BUTTON_PRESSED())
continue;
delay(1);
}
while (! IS_BUTTON_PRESSED());
RGB(0x001040);
delay(50);
return 1;
}
// Must be implemented by application
// data is HID_MESSAGE_SIZE long in bytes
#ifndef TEST_POWER
void ctaphid_write_block(uint8_t * data)
{
printf1(TAG_DUMP,"<< "); dump_hex1(TAG_DUMP, data, HID_MESSAGE_SIZE);
usbhid_send(data);
}
#endif
#ifdef IS_BOOTLOADER // two different colors between bootloader and app
void heartbeat()
{
static int state = 0;
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
int but = IS_BUTTON_PRESSED();
if (state)
{
val--;
}
else
{
val++;
}
if (val > 30 || val < 1)
{
state = !state;
}
// if (but) RGB(val * 2);
// else
RGB((val << 16) | (val*2 << 8));
}
#else
void heartbeat()
{
static int state = 0;
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
int but = IS_BUTTON_PRESSED();
#if 0
RGB(0x100000); // bright ass light
return;
#endif
if (state)
{
val--;
}
else
{
val++;
}
if (val >120/3 || val < 1)
{
state = !state;
}
if (but) RGB(val * 2);
else RGB(val*3 | ((val*3) << 8) | (val << 16) );
// else RGB((val*3) << 8);
}
#endif
uint32_t millis()
{
return CRYOTIMER->CNT;
}
void usbhid_init()
{
}
static int msgs_to_recv = 0;
static void wait_for_efm8_ready()
{
// Wait for efm8 to be ready
while (GPIO_PinInGet(RDY_PIN) == 0)
;
}
static void wait_for_efm8_busy()
{
// Wait for efm8 to be ready
while (GPIO_PinInGet(RDY_PIN) != 0)
;
}
#ifndef TEST_POWER
int usbhid_recv(uint8_t * msg)
{
int i;
if (GPIO_PinInGet(MSG_AVAIL_PIN) == 0)
{
GPIO_PinOutClear(RW_PIN); // Drive low to indicate READ
wait_for_efm8_ready();
for (i = 0; i < 64; i++)
{
msg[i] = USART_SpiTransfer(USART1, 'A');
// delay(1);
}
GPIO_PinOutSet(RW_PIN);
wait_for_efm8_busy();
// // msgs_to_recv--;
// printf(">> ");
// dump_hex(msg,64);
return 64;
}
return 0;
}
#endif
void usbhid_send(uint8_t * msg)
{
int i;
// uint32_t t1 = millis();
USART_SpiTransfer(USART1, *msg++); // Send 1 byte
wait_for_efm8_ready();
for (i = 1; i < HID_MESSAGE_SIZE; i++)
{
USART_SpiTransfer(USART1, *msg++);
}
wait_for_efm8_busy();
delay(10);
// uint32_t t2 = millis();
// printf("wait time: %u\n", (uint32_t)(t2-t1));
}
void usbhid_close()
{
}
void main_loop_delay()
{
}
void delay(int ms)
{
int t1 = millis();
while(millis() - t1 < ms)
;
}
void GPIO_ODD_IRQHandler()
{
uint32_t flag = GPIO->IF;
GPIO->IFC = flag;
if (flag & (1<<9))
{
// printf("pin 9 interrupt\r\n");
msgs_to_recv++;
}
else
{
printf1(TAG_ERR,"wrong pin int %x\r\n",flag);
}
}
void init_adc()
{
/* Enable ADC Clock */
CMU_ClockEnable(cmuClock_ADC0, true);
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
/* Initialize the ADC with the required values */
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(7000000, 0);
ADC_Init(ADC0, &init);
/* Initialize for single conversion specific to RNG */
singleInit.reference = adcRefVEntropy;
singleInit.diff = true;
singleInit.posSel = adcPosSelVSS;
singleInit.negSel = adcNegSelVSS;
ADC_InitSingle(ADC0, &singleInit);
/* Set VINATT to maximum value and clear FIFO */
ADC0->SINGLECTRLX |= _ADC_SINGLECTRLX_VINATT_MASK;
ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
}
void authenticator_read_state(AuthenticatorState * state)
{
uint32_t * ptr = PAGE_SIZE*STATE1_PAGE;
memmove(state,ptr,sizeof(AuthenticatorState));
}
void authenticator_read_backup_state(AuthenticatorState * state )
{
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
memmove(state,ptr,sizeof(AuthenticatorState));
}
void authenticator_write_state(AuthenticatorState * state, int backup)
{
uint32_t * ptr;
if (! backup)
{
ptr = PAGE_SIZE*STATE1_PAGE;
MSC_ErasePage(ptr);
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
}
else
{
ptr = PAGE_SIZE*STATE2_PAGE;
MSC_ErasePage(ptr);
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
}
}
// Return 1 yes backup is init'd, else 0
int authenticator_is_backup_initialized()
{
uint8_t header[16];
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
memmove(header,ptr,16);
AuthenticatorState * state = (AuthenticatorState*)header;
return state->is_initialized == INITIALIZED_MARKER;
}
uint8_t adc_rng(void);
void reset_efm8()
{
// Reset EFM8
GPIO_PinOutClear(RESET_PIN);
delay(2);
GPIO_PinOutSet(RESET_PIN);
}
void bootloader_init(void)
{
/* Chip errata */
// Reset EFM8
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
// status LEDS
GPIO_PinModeSet(LED_RED_PIN,
gpioModePushPull,
1); // red
GPIO_PinModeSet(LED_GREEN_PIN,
gpioModePushPull,
1); // green
GPIO_PinModeSet(LED_BLUE_PIN,
gpioModePushPull,
1); // blue
// EFM8 RDY/BUSY
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
// EFM8 MSG Available
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
// SPI R/w Indicator
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
printing_init();
MSC_Init();
}
void device_init(void)
{
/* Chip errata */
CHIP_Init();
enter_DefaultMode_from_RESET();
// status LEDS
GPIO_PinModeSet(LED_RED_PIN,
gpioModePushPull,
1); // red
GPIO_PinModeSet(LED_GREEN_PIN,
gpioModePushPull,
1); // green
GPIO_PinModeSet(LED_BLUE_PIN,
gpioModePushPull,
1); // blue
// EFM8 RDY/BUSY
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
// EFM8 MSG Available
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
// SPI R/w Indicator
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
// Reset EFM8
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
TIMER_TopSet(TIMER0, 255);
RGB(LED_INIT_VALUE);
printing_init();
init_adc();
MSC_Init();
init_atomic_counter();
if (sizeof(AuthenticatorState) > PAGE_SIZE)
{
printf2(TAG_ERR, "not enough room in page\n");
exit(1);
}
CborEncoder test;
uint8_t buf[64];
cbor_encoder_init(&test, buf, 20, 0);
reset_efm8();
printf1(TAG_GEN,"Device init\r\n");
int i=0;
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = adc_rng();
}
}
#ifdef IS_BOOTLOADER
typedef enum
{
BootWrite = 0x40,
BootDone = 0x41,
BootCheck = 0x42,
BootErase = 0x43,
} WalletOperation;
typedef struct {
uint8_t op;
uint8_t addr[3];
uint8_t tag[4];
uint8_t len;
uint8_t payload[255 - 9];
} __attribute__((packed)) BootloaderReq;
//#define APPLICATION_START_ADDR 0x8000
//#define APPLICATION_START_PAGE (0x8000/PAGE_SIZE)
//#define APPLICATION_END_ADDR (PAGE_SIZE*125-4) // NOT included in application
static void erase_application()
{
int page;
uint32_t * ptrpage;
for(page = APPLICATION_START_PAGE; page < APPLICATION_END_PAGE; page++)
{
ptrpage = page * PAGE_SIZE;
MSC_ErasePage(ptrpage);
}
}
static void authorize_application()
{
uint32_t zero = 0;
uint32_t * ptr;
ptr = AUTH_WORD_ADDR;
MSC_WriteWordFast(ptr,&zero, 4);
}
int bootloader_bridge(uint8_t klen, uint8_t * keyh)
{
static int has_erased = 0;
BootloaderReq * req = (BootloaderReq * )keyh;
uint8_t payload[256];
uint8_t hash[32];
uint8_t * pubkey = (uint8_t*)"\x57\xe6\x80\x39\x56\x46\x2f\x0c\x95\xac\x72\x71\xf0\xbc\xe8\x2d\x67\xd0\x59\x29\x2e\x15\x22\x89\x6a\xbd\x3f\x7f\x27\xf3\xc0\xc6\xe2\xd7\x7d\x8a\x9f\xcc\x53\xc5\x91\xb2\x0c\x9c\x3b\x4e\xa4\x87\x31\x67\xb4\xa9\x4b\x0e\x8d\x06\x67\xd8\xc5\xef\x2c\x50\x4a\x55";
const struct uECC_Curve_t * curve = NULL;
/*printf("bootloader_bridge\n");*/
if (req->len > 255-9)
{
return CTAP1_ERR_INVALID_LENGTH;
}
memset(payload, 0xff, sizeof(payload));
memmove(payload, req->payload, req->len);
uint32_t addr = (*((uint32_t*)req->addr)) & 0xffffff;
uint32_t * ptr = addr;
switch(req->op){
case BootWrite:
/*printf("BootWrite 0x%08x\n", addr);*/
if (ptr < APPLICATION_START_ADDR || ptr >= APPLICATION_END_ADDR)
{
return CTAP2_ERR_NOT_ALLOWED;
}
if (!has_erased)
{
erase_application();
has_erased = 1;
}
if (is_authorized_to_boot())
{
printf2(TAG_ERR, "Error, boot check bypassed\n");
exit(1);
}
MSC_WriteWordFast(ptr,payload, req->len + (req->len%4));
break;
case BootDone:
// printf("BootDone\n");
ptr = APPLICATION_START_ADDR;
crypto_sha256_init();
crypto_sha256_update(ptr, APPLICATION_END_ADDR-APPLICATION_START_ADDR);
crypto_sha256_final(hash);
// printf("hash: "); dump_hex(hash, 32);
// printf("sig: "); dump_hex(payload, 64);
curve = uECC_secp256r1();
if (! uECC_verify(pubkey,
hash,
32,
payload,
curve))
{
return CTAP2_ERR_OPERATION_DENIED;
}
authorize_application();
REBOOT_FLAG = 1;
break;
case BootCheck:
/*printf("BootCheck\n");*/
return 0;
break;
case BootErase:
/*printf("BootErase\n");*/
erase_application();
return 0;
break;
default:
return CTAP1_ERR_INVALID_COMMAND;
}
return 0;
}
int is_authorized_to_boot()
{
uint32_t * auth = AUTH_WORD_ADDR;
return *auth == 0;
}
#endif

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <stdio.h>
#include <string.h>
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_core.h"
#include "em_gpio.h"
#include "InitDevice.h"
#include "app.h"
#include "cbor.h"

View File

@ -1,382 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* nfc.c
*
* Created on: Jul 22, 2018
* Author: conor
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "em_chip.h"
#include "em_gpio.h"
#include "em_i2c.h"
#include "log.h"
#include "util.h"
#include "nfc.h"
#include "app.h"
#define NFC_DEV_ADDR (0xa0|(0x0<<1))
#define NFC_DEV_USART USART1
#ifndef IS_BOOTLOADER
I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
{
I2C_TransferReturn_TypeDef ret;
uint32_t timeout = 10000;
/* Do a polled transfer */
ret = I2C_TransferInit(i2c, seq);
while (ret == i2cTransferInProgress && timeout--)
{
ret = I2C_Transfer(i2c);
}
return ret;
}
// data must be 16 bytes
void read_block(uint8_t block, uint8_t * data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_read_data[16];
uint8_t i2c_write_data[1];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE_READ;
/* Select command to issue */
i2c_write_data[0] = block;
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 1;
/* Select location/length of data to be read */
seq.buf[1].data = i2c_read_data;
seq.buf[1].len = 16;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
memmove(data, i2c_read_data, 16);
}
// data must be 16 bytes
void write_block(uint8_t block, uint8_t * data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_write_data[1 + 16];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE;
/* Select command to issue */
i2c_write_data[0] = block;
memmove(i2c_write_data + 1, data, 16);
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 17;
/* Select location/length of data to be read */
seq.buf[1].data = NULL;
seq.buf[1].len = 0;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
}
void write_reg_flash(uint8_t reg_addr, uint8_t mask,uint8_t data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_write_data[4];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE;
i2c_write_data[0] = 0x3a;
i2c_write_data[1] = reg_addr;
i2c_write_data[2] = mask;
i2c_write_data[3] = data;
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 4;
seq.buf[1].data = NULL;
seq.buf[1].len = 0;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
}
void write_reg(uint8_t reg_addr, uint8_t data)
{
uint8_t mode = 0x00 | (reg_addr & 0x1f);
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = USART_SpiTransfer(NFC_DEV_USART, data);
GPIO_PinOutSet(NFC_DEV_SS);
}
void write_command(uint8_t cmd)
{
uint8_t mode = cmd;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
void write_eeprom(uint8_t block, uint8_t * data)
{
uint8_t mode = 0x40;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = block << 1;
USART_SpiTransfer(NFC_DEV_USART, mode);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
void read_eeprom(uint8_t block, uint8_t * data)
{
uint8_t mode = 0x7f;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = block << 1;
USART_SpiTransfer(NFC_DEV_USART, mode);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
uint8_t read_reg(uint8_t reg_addr)
{
uint8_t mode = 0x20 | (reg_addr & 0x1f);
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
// printf("%02x: %x\n",(reg_addr),(int)mode);
return mode;
}
void read_buffer(uint8_t * data, int len)
{
uint8_t mode = 0xC0;
int i;
if (len > 32)
{
printf("warning, max len is 32\n");
len = 32;
}
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
for(i = 0; i < len; i++)
{
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
}
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
// data must be 14 bytes long
void read_reg_block(uint8_t * data)
{
int i;
uint8_t mode = 0x20 | (0 & 0x1f);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
for (i = 0; i < 0x20; i++)
{
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
if (i < 6 || (i >=8 && i < 0x0f) || (i >= 0x1e))
{
*data = mode;
data++;
}
}
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
typedef struct {
uint8_t header;
uint8_t tlen;
uint8_t plen;
uint8_t ilen;
uint8_t rtype;
} NDEF;
typedef struct {
uint8_t io;
uint8_t conf0;
uint8_t conf1;
uint8_t conf2;
uint8_t rfid_status;
uint8_t ic_status;
uint8_t mask0;
uint8_t mask1;
uint8_t int0;
uint8_t int1;
uint8_t buf_status2;
uint8_t buf_status1;
uint8_t last_nfc_address;
uint8_t maj;
uint8_t minor;
} __attribute__((packed)) AMS_REGS;
void nfc_test()
{
uint8_t data[32];
uint8_t ns_reg;
uint8_t last_ns_reg;
// magic-number,
uint8_t cc[] = {0xE1,0x10,0x08, 0x00};
uint8_t ndef[32] = "\x03\x11\xD1\x01\x0D\x55\x01adafruit.com";
AMS_REGS * regs;
return ;
delay(10);
GPIO_PinOutSet(NFC_DEV_SS);
delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(10);
// uint8_t reg = read_reg(0);
write_command(0xC2); // Set to default state
write_command(0xC4); // Clear buffer
write_reg(0x3, 0x80 | 0x40); // enable tunneling mode and RF configuration
read_reg_block(data);
printf("regs: "); dump_hex(data,15);
delay(100);
read_reg_block(data);
printf("regs: "); dump_hex(data,15);
if (0)
{
read_eeprom(0x7F, data);
printf("initial config: "); dump_hex(data,4);
data[0] = (1<<2) | 0x03; // save cfg1 setting for energy harvesting
data[1] = 0x80 | 0x40; // save cfg2 setting for tunneling
write_eeprom(0x7F, data);
printf("updated config: "); dump_hex(data,4);
}
while (1)
{
// delay(100);
// read_reg_block(data);
// regs = (AMS_REGS *)data;
//
// if ((regs->buf_status2 & 0x3f) && !(regs->buf_status2 & 0x80))
// {
// read_buffer(data, regs->buf_status2 & 0x3f);
// printf("data: ");
//
// dump_hex(data, regs->buf_status2 & 0x3f);
// }
// dump_hex(data,15);
}
}
#endif

View File

@ -1,105 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_core.h"
#include "em_usart.h"
#include "em_gpio.h"
#include <stdio.h>
#include <string.h>
#include "app.h"
#ifndef PRINTING_USE_VCOM
int RETARGET_WriteChar(char c)
{
return ITM_SendChar(c);
}
int RETARGET_ReadChar(void)
{
return 0;
}
void setupSWOForPrint(void)
{
/* Enable GPIO clock. */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Enable Serial wire output pin */
GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN;
/* Set location 0 */
GPIO->ROUTELOC0 = GPIO_ROUTELOC0_SWVLOC_LOC0;
/* Enable output on pin - GPIO Port F, Pin 2 */
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
/* Enable debug clock AUXHFRCO */
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, true);
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
/* Enable trace in core debug */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
ITM->LAR = 0xC5ACCE55;
ITM->TER = 0x0;
ITM->TCR = 0x0;
TPI->SPPR = 2;
TPI->ACPR = 0x15; // changed from 0x0F on Giant, etc. to account for 19 MHz default AUXHFRCO frequency
ITM->TPR = 0x0;
DWT->CTRL = 0x400003FE;
ITM->TCR = 0x0001000D;
TPI->FFCR = 0x00000100;
ITM->TER = 0x1;
}
void printing_init()
{
setupSWOForPrint();
}
#else
int RETARGET_WriteChar(char c)
{
USART_Tx(USART0,c);
return 0;
}
int RETARGET_ReadChar(void)
{
return 0;
}
void printing_init()
{
#ifdef USING_DEV_BOARD
// GPIO_PinModeSet(gpioPortA,5,gpioModePushPull,1); // VCOM enable
#endif
}
#endif

View File

@ -1,475 +0,0 @@
/***************************************************************************//**
* @file
* @brief Provide stdio retargeting for all supported toolchains.
* @version 5.5.0
*******************************************************************************
* # License
* <b>Copyright 2015 Silicon Labs, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silabs License Agreement. See the file
* "Silabs_License_Agreement.txt" for details. Before using this software for
* any purpose, you must agree to the terms of that agreement.
*
******************************************************************************/
/***************************************************************************//**
* @addtogroup RetargetIo
* @{ This module provide low-level stubs for retargetting stdio for all
* supported toolchains.
* The stubs are minimal yet sufficient implementations.
* Refer to chapter 12 in the reference manual for newlib 1.17.0
* for details on implementing newlib stubs.
******************************************************************************/
extern int RETARGET_ReadChar(void);
extern int RETARGET_WriteChar(char c);
#if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "em_device.h"
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
int fileno(FILE *);
/** @endcond */
int _close(int file);
int _fstat(int file, struct stat *st);
int _isatty(int file);
int _lseek(int file, int ptr, int dir);
int _read(int file, char *ptr, int len);
caddr_t _sbrk(int incr);
int _write(int file, const char *ptr, int len);
extern char _end; /**< Defined by the linker */
/**************************************************************************//**
* @brief
* Close a file.
*
* @param[in] file
* File you want to close.
*
* @return
* Returns 0 when the file is closed.
*****************************************************************************/
int _close(int file)
{
(void) file;
return 0;
}
/**************************************************************************//**
* @brief Exit the program.
* @param[in] status The value to return to the parent process as the
* exit status (not used).
*****************************************************************************/
void _exit(int status)
{
(void) status;
while (1) {
} /* Hang here forever... */
}
/**************************************************************************//**
* @brief
* Status of an open file.
*
* @param[in] file
* Check status for this file.
*
* @param[in] st
* Status information.
*
* @return
* Returns 0 when st_mode is set to character special.
*****************************************************************************/
int _fstat(int file, struct stat *st)
{
(void) file;
st->st_mode = S_IFCHR;
return 0;
}
/**************************************************************************//**
* @brief Get process ID.
*****************************************************************************/
int _getpid(void)
{
return 1;
}
/**************************************************************************//**
* @brief
* Query whether output stream is a terminal.
*
* @param[in] file
* Descriptor for the file.
*
* @return
* Returns 1 when query is done.
*****************************************************************************/
int _isatty(int file)
{
(void) file;
return 1;
}
/**************************************************************************//**
* @brief Send signal to process.
* @param[in] pid Process id (not used).
* @param[in] sig Signal to send (not used).
*****************************************************************************/
int _kill(int pid, int sig)
{
(void)pid;
(void)sig;
return -1;
}
/**************************************************************************//**
* @brief
* Set position in a file.
*
* @param[in] file
* Descriptor for the file.
*
* @param[in] ptr
* Poiter to the argument offset.
*
* @param[in] dir
* Directory whence.
*
* @return
* Returns 0 when position is set.
*****************************************************************************/
int _lseek(int file, int ptr, int dir)
{
(void) file;
(void) ptr;
(void) dir;
return 0;
}
/**************************************************************************//**
* @brief
* Read from a file.
*
* @param[in] file
* Descriptor for the file you want to read from.
*
* @param[in] ptr
* Pointer to the chacaters that are beeing read.
*
* @param[in] len
* Number of characters to be read.
*
* @return
* Number of characters that have been read.
*****************************************************************************/
int _read(int file, char *ptr, int len)
{
int c, rxCount = 0;
(void) file;
while (len--) {
if ((c = RETARGET_ReadChar()) != -1) {
*ptr++ = c;
rxCount++;
} else {
break;
}
}
if (rxCount <= 0) {
return -1; /* Error exit */
}
return rxCount;
}
/**************************************************************************//**
* @brief
* Increase heap.
*
* @param[in] incr
* Number of bytes you want increment the program's data space.
*
* @return
* Rsturns a pointer to the start of the new area.
*****************************************************************************/
caddr_t _sbrk(int incr)
{
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_end;
}
prev_heap_end = heap_end;
heap_end += incr;
return (caddr_t) prev_heap_end;
}
/**************************************************************************//**
* @brief
* Write to a file.
*
* @param[in] file
* Descriptor for the file you want to write to.
*
* @param[in] ptr
* Pointer to the text you want to write
*
* @param[in] len
* Number of characters to be written.
*
* @return
* Number of characters that have been written.
*****************************************************************************/
int _write(int file, const char *ptr, int len)
{
int txCount;
(void) file;
for (txCount = 0; txCount < len; txCount++) {
RETARGET_WriteChar(*ptr++);
}
return len;
}
#endif /* !defined( __CROSSWORKS_ARM ) && defined( __GNUC__ ) */
#if defined(__ICCARM__)
/*******************
*
* Copyright 1998-2003 IAR Systems. All rights reserved.
*
* $Revision: 38614 $
*
* This is a template implementation of the "__write" function used by
* the standard library. Replace it with a system-specific
* implementation.
*
* The "__write" function should output "size" number of bytes from
* "buffer" in some application-specific way. It should return the
* number of characters written, or _LLIO_ERROR on failure.
*
* If "buffer" is zero then __write should perform flushing of
* internal buffers, if any. In this case "handle" can be -1 to
* indicate that all handles should be flushed.
*
* The template implementation below assumes that the application
* provides the function "MyLowLevelPutchar". It should return the
* character written, or -1 on failure.
*
********************/
#include <yfuns.h>
#include <stdint.h>
#include "em_common.h"
_STD_BEGIN
/**************************************************************************//**
* @brief Transmit buffer to USART1
* @param buffer Array of characters to send
* @param nbytes Number of bytes to transmit
* @return Number of bytes sent
*****************************************************************************/
static int TxBuf(uint8_t *buffer, int nbytes)
{
int i;
for (i = 0; i < nbytes; i++) {
RETARGET_WriteChar(*buffer++);
}
return nbytes;
}
/*
* If the __write implementation uses internal buffering, uncomment
* the following line to ensure that we are called with "buffer" as 0
* (i.e. flush) when the application terminates.
*/
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
/* Remove the #if #endif pair to enable the implementation */
size_t nChars = 0;
if (buffer == 0) {
/*
* This means that we should flush internal buffers. Since we
* don't we just return. (Remember, "handle" == -1 means that all
* handles should be flushed.)
*/
return 0;
}
/* This template only writes to "standard out" and "standard err",
* for all other file handles it returns failure. */
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
return _LLIO_ERROR;
}
/* Hook into USART1 transmit function here */
if (TxBuf((uint8_t *) buffer, size) != size) {
return _LLIO_ERROR;
} else {
nChars = size;
}
return nChars;
}
size_t __read(int handle, unsigned char * buffer, size_t size)
{
/* Remove the #if #endif pair to enable the implementation */
int nChars = 0;
/* This template only reads from "standard in", for all other file
* handles it returns failure. */
if (handle != _LLIO_STDIN) {
return _LLIO_ERROR;
}
for (/* Empty */; size > 0; --size) {
int c = RETARGET_ReadChar();
if (c < 0) {
break;
}
*buffer++ = c;
++nChars;
}
return nChars;
}
_STD_END
#endif /* defined( __ICCARM__ ) */
#if defined(__CROSSWORKS_ARM)
/* Pass each of these function straight to the USART */
int __putchar(int ch)
{
return(RETARGET_WriteChar(ch));
}
int __getchar(void)
{
return(RETARGET_ReadChar());
}
#endif /* defined( __CROSSWORKS_ARM ) */
#if defined(__CC_ARM)
/******************************************************************************/
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/
#include <stdio.h>
/* #pragma import(__use_no_semihosting_swi) */
struct __FILE{
int handle;
};
/**Standard output stream*/
FILE __stdout;
/**************************************************************************//**
* @brief
* Writes character to file
*
* @param[in] f
* File
*
* @param[in] ch
* Character
*
* @return
* Written character
*****************************************************************************/
int fputc(int ch, FILE *f)
{
return(RETARGET_WriteChar(ch));
}
/**************************************************************************//**
* @brief
* Reads character from file
*
* @param[in] f
* File
*
* @return
* Character
*****************************************************************************/
int fgetc(FILE *f)
{
return(RETARGET_ReadChar());
}
/**************************************************************************//**
* @brief
* Tests the error indicator for the stream pointed
* to by file
*
* @param[in] f
* File
*
* @return
* Returns non-zero if it is set
*****************************************************************************/
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
/**************************************************************************//**
* @brief
* Writes a character to the console
*
* @param[in] ch
* Character
*****************************************************************************/
void _ttywrch(int ch)
{
RETARGET_WriteChar(ch);
}
/**************************************************************************//**
* @brief
* Library exit function. This function is called if stack
* overflow occurs.
*
* @param[in] return_code
* Return code
*****************************************************************************/
void _sys_exit(int return_code)
{
label: goto label;/* endless loop */
}
#endif /* defined( __CC_ARM ) */
/** @} (end group RetargetIo) */

View File

@ -1,210 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Debug">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32JG1B200F128GM32 EFM32JG1B200F128GM32" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="com.silabs.board.none:0.0.0" projectCommon.partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.drivers\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.bsp\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s&quot;,&quot;CMSIS/EFM32JG1B/system_efm32jg1b.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.part\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_system.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_assert.c&quot;,&quot;emlib/em_emu.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_device.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_chip.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.board\&quot;/&gt;&quot;}]" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.930698941" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.2037798819" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash.495029551" name="Override default flash options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength.2021030475" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength" value="0x4000" valueType="string"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram.2020332041" name="Override default RAM options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin.2081162957" name="ORIGIN" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin" value="0x20000000" valueType="string"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength.1981650487" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength" value="0x8000" valueType="string"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.613101530" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.2113865201" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.1400029735" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.size" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.115820704" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DEBUG=1"/>
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.422869633" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.384018529" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.749408413" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../efm32/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../fido2&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../fido2/extensions&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../tinycbor/src&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/sha256&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/micro-ecc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/tiny-AES-c&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.856016047" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="gnu.cpp.compiler.option.optimization.level.1012646883" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1020668095" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.304697844" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="true" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.718152493" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.998368574" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.604334894" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
</option>
<inputType id="org.eclipse.cdt.core.asmSource.695503458" superClass="org.eclipse.cdt.core.asmSource"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.1884456996" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1998445955" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.185802893" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1862357894" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1275127827" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="CMSIS/EFM32PG1B|crypto|efm32|fido2" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry excluding="aes-gcm|micro-ecc/examples|micro-ecc/scripts|micro-ecc/test|tiny-AES-c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="crypto"/>
<entry excluding=".settings|CMSIS|docs|emlib|GNU ARM v7.2.1 - Debug|hw|inc|mbedtls|sl_crypto|src/crypto.c|src/main.c|.cproject|.project|EFM32.hwconf|Makefile|src/.crypto.c.swp|src/.device.c.swp|src/app.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="efm32"/>
<entry excluding=".main.c.swp|crypto.c|ctap_parse.c|main.c|.ctap_errors.h.swp|.ctap.c.swp|.ctap.h.swp|.storage.h.swp|.wallet.c.swp|.wallet.h.swp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fido2"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Release">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32PG1B200F256GM48 EFM32PG1B200F256GM48" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_system.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_assert.c&quot;,&quot;emlib/em_emu.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_device.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_chip.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.board\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.s&quot;,&quot;CMSIS/EFM32PG1B/system_efm32pg1b.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.part\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.bsp\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.drivers\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Release" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.1542058136" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.704282697" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.67671565" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Release" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.805468153" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.992246362" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.1037480919" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG=1"/>
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.951908916" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.1884913917" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="false" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.1968865334" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1495369104" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1435596684" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.258094144" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="false" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.947557425" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.220914305" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.1679775183" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
</option>
<inputType id="org.eclipse.cdt.core.asmSource.1025131309" superClass="org.eclipse.cdt.core.asmSource"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.158700898" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1339758179" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1667537250" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.305372504" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.29462529" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="efm32/CMSIS/EFM32JG1B|CMSIS/EFM32JG1B" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" project.generation="92" projectCommon.boardIds="brd2500a:0.0.0" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="efm32boot.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.501778116" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>efm32boot</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
</natures>
<linkedResources>
<link>
<name>crypto</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/crypto</locationURI>
</link>
<link>
<name>efm32</name>
<type>2</type>
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/efm32</locationURI>
</link>
<link>
<name>fido2</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/fido2</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,2 +0,0 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -1,317 +0,0 @@
/* @file startup_efm32pg1b.S
* @brief startup file for Silicon Labs EFM32PG1B devices.
* For use with GCC for ARM Embedded Processors
* @version 5.2.2
* Date: 12 June 2014
*
*/
/* Copyright (c) 2011 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000C00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long EMU_IRQHandler /* 0 - EMU */
.long Default_Handler /* 1 - Reserved */
.long WDOG0_IRQHandler /* 2 - WDOG0 */
.long Default_Handler /* 3 - Reserved */
.long Default_Handler /* 4 - Reserved */
.long Default_Handler /* 5 - Reserved */
.long Default_Handler /* 6 - Reserved */
.long Default_Handler /* 7 - Reserved */
.long LDMA_IRQHandler /* 8 - LDMA */
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 10 - TIMER0 */
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
.long ACMP0_IRQHandler /* 13 - ACMP0 */
.long ADC0_IRQHandler /* 14 - ADC0 */
.long IDAC0_IRQHandler /* 15 - IDAC0 */
.long I2C0_IRQHandler /* 16 - I2C0 */
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
.long TIMER1_IRQHandler /* 18 - TIMER1 */
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
.long LEUART0_IRQHandler /* 21 - LEUART0 */
.long PCNT0_IRQHandler /* 22 - PCNT0 */
.long CMU_IRQHandler /* 23 - CMU */
.long MSC_IRQHandler /* 24 - MSC */
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long Default_Handler /* 27 - Reserved */
.long Default_Handler /* 28 - Reserved */
.long RTCC_IRQHandler /* 29 - RTCC */
.long Default_Handler /* 30 - Reserved */
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
.long Default_Handler /* 32 - Reserved */
.long FPUEH_IRQHandler /* 33 - FPUEH */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __zero_table_start__ and __zero_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler EMU_IRQHandler
def_irq_handler WDOG0_IRQHandler
def_irq_handler LDMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler IDAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler CRYPTO_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler RTCC_IRQHandler
def_irq_handler CRYOTIMER_IRQHandler
def_irq_handler FPUEH_IRQHandler
.end

View File

@ -1,389 +0,0 @@
/***************************************************************************//**
* @file system_efm32pg1b.c
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
* @version 5.2.2
******************************************************************************
* # License
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
* has no obligation to support this Software. Silicon Laboratories, Inc. is
* providing the Software "AS IS", with no express or implied warranties of any
* kind, including, but not limited to, any implied warranties of
* merchantability or fitness for any particular purpose or warranties against
* infringement of any proprietary rights of a third party.
*
* Silicon Laboratories, Inc. will not be liable for any consequential,
* incidental, or special damages, or any other relief, or for any claim by
* any third party, arising from your use of this Software.
*
*****************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
/** ULFRCO frequency */
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFRCO_MAX_FREQ
/** Maximum HFRCO frequency */
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
#endif
#ifndef EFM32_HFXO_FREQ
/** HFXO frequency */
#define EFM32_HFXO_FREQ (40000000UL)
#endif
#ifndef EFM32_HFRCO_STARTUP_FREQ
/** HFRCO startup frequency */
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
/** LFXO frequency */
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = 32768UL;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
/**
* @brief
* System HFRCO frequency
*
* @note
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
*
* @details
* Frequency of the system HFRCO oscillator
*/
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
uint32_t presc;
ret = SystemHFClockGet();
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
_CMU_HFCOREPRESC_PRESC_SHIFT;
ret /= (presc + 1);
/* Keep CMSIS system clock variable up-to-date */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the maximum core clock frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The maximum core clock frequency in Hz.
******************************************************************************/
uint32_t SystemMaxCoreClockGet(void)
{
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
{
case CMU_HFCLKSTATUS_SELECTED_LFXO:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_HFCLKSTATUS_SELECTED_HFXO:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
ret = SystemHfrcoFreq;
break;
}
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
>> _CMU_HFPRESC_PRESC_SHIFT));
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Set floating point coprosessor access mode. */
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
(3UL << 11*2) ); /* set CP11 Full Access */
#endif
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,81 +0,0 @@
/***************************************************************************//**
* @file em_assert.c
* @brief Assert API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#include <stdbool.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ASSERT
* @{
******************************************************************************/
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* This implementation simply enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* @note
* This function is not used unless @ref DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @param[in] file
* Name of source file where assertion failed.
*
* @param[in] line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (true) {
}
}
#endif /* DEBUG_EFM */
/** @} (end addtogroup ASSERT) */
/** @} (end addtogroup emlib) */

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/***************************************************************************//**
* @file em_cryotimer.c
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cryotimer.h"
#include "em_bus.h"
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
/***************************************************************************//**
* @brief
* Initialize the CRYOTIMER.
*
* @details
* Use this function to initialize the CRYOTIMER.
* Select prescaler setting and select low frequency oscillator.
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
* details.
*
* @param[in] init
* Pointer to initialization structure.
******************************************************************************/
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
{
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
}
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +0,0 @@
/***************************************************************************//**
* @file em_gpio.c
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @details
* This module contains functions to control the GPIO peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The GPIO peripheral is used for pin configuration
* and direct pin manipulation and sensing as well as routing for peripheral
* pin connections.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
#define GPIO_STRENGHT_VALID(strenght) (!((strenght) \
& ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \
| _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined (_GPIO_ROUTE_SWLOCATION_MASK)
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK)
| (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
#endif
#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
/***************************************************************************//**
* @brief
* Sets the drive strength for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] strength
* Drive strength to use for port.
******************************************************************************/
void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,
GPIO_DriveStrength_TypeDef strength)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));
BUS_RegMaskedWrite(&GPIO->P[port].CTRL,
_GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,
strength);
}
#endif
/***************************************************************************//**
* @brief
* Configure GPIO external pin interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected interrupt is cleared
* by this function.
*
* @note
* On series 0 devices the pin number parameter is not used. The
* pin number used on these devices is hardwired to the interrupt with the
* same number. @n
* On series 1 devices, pin number can be selected freely within a group.
* Interrupt numbers are divided into 4 groups (intNo / 4) and valid pin
* number within the interrupt groups are:
* 0: pins 0-3
* 1: pins 4-7
* 2: pins 8-11
* 3: pins 12-15
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The pin number on the port.
*
* @param[in] intNo
* The interrupt number to trigger.
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
unsigned int intNo,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp = 0;
#if !defined(_GPIO_EXTIPINSELL_MASK)
(void)pin;
#endif
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
#if defined(_GPIO_EXTIPINSELL_MASK)
EFM_ASSERT(GPIO_INTNO_PIN_VALID(intNo, pin));
#endif
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPSELL,
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo),
port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo));
} else {
tmp = intNo - 8;
BUS_RegMaskedWrite(&GPIO->EXTIPSELH,
_GPIO_EXTIPSELH_EXTIPSEL8_MASK
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp),
port << (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#if defined(_GPIO_EXTIPINSELL_MASK)
/* There are two registers controlling the interrupt/pin number mapping:
* The EXTIPINSELL register controls interrupt 0-7 and EXTIPINSELH controls
* interrupt 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELL,
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo),
((pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo));
} else {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELH,
_GPIO_EXTIPINSELH_EXTIPINSEL8_MASK
<< (_GPIO_EXTIPINSELH_EXTIPINSEL9_SHIFT * tmp),
((pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL8_MASK)
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#endif
/* Enable/disable rising edge */
BUS_RegBitWrite(&(GPIO->EXTIRISE), intNo, risingEdge);
/* Enable/disable falling edge */
BUS_RegBitWrite(&(GPIO->EXTIFALL), intNo, fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << intNo;
/* Finally enable/disable interrupt */
BUS_RegBitWrite(&(GPIO->IEN), intNo, enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8) {
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xFu << (pin * 4)))
| (mode << (pin * 4));
} else {
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xFu << ((pin - 8) * 4)))
| (mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
}
/***************************************************************************//**
* @brief
* Get the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @return
* The pin mode.
******************************************************************************/
GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
if (pin < 8) {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEL >> (pin * 4)) & 0xF);
} else {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEH >> ((pin - 8) * 4)) & 0xF);
}
}
#if defined(_GPIO_EM4WUEN_MASK)
/**************************************************************************//**
* @brief
* Enable GPIO pin wake-up from EM4. When the function exits,
* EM4 mode can be safely entered.
*
* @note
* It is assumed that the GPIO pin modes are set correctly.
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
* @param[in] polaritymask
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
#if defined(_GPIO_EM4WUPOL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
GPIO->EM4WUPOL |= pinmask & polaritymask;
#elif defined(_GPIO_EXTILEVEL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);
GPIO->EXTILEVEL &= ~pinmask;
GPIO->EXTILEVEL |= pinmask & polaritymask;
#endif
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
#if defined(_GPIO_CMD_EM4WUCLR_MASK)
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
#elif defined(_GPIO_IFC_EM4WU_MASK)
GPIO_IntClear(pinmask);
#endif
}
#endif
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup emlib) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/***************************************************************************//**
* @file em_system.c
* @brief System Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
#include <stddef.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
/* CHIP FAMILY bit [5:2] */
tmp = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);
/* CHIP FAMILY bit [1:0] */
tmp |= ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);
rev->family = tmp;
/* CHIP MAJOR bit [3:0] */
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
/* CHIP MINOR bit [7:4] */
tmp = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
/* CHIP MINOR bit [3:0] */
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Peripheral calibration register address to get calibration value for. If
* a calibration value is found then this register is updated with the
* calibration value.
*
* @return
* True if a calibration value exists, false otherwise.
******************************************************************************/
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
SYSTEM_CalAddrVal_TypeDef * p, * end;
p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000);
end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE;
for (; p < end; p++) {
if (p->address == 0xFFFFFFFF) {
/* Found table terminator */
return false;
}
if (p->address == (uint32_t)regAddress) {
*regAddress = p->calValue;
return true;
}
}
/* Nothing found for regAddress */
return false;
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup emlib) */

View File

@ -1,253 +0,0 @@
/***************************************************************************//**
* @file em_timer.c
* @brief Timer/counter (TIMER) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_timer.h"
#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @brief Timer/Counter (TIMER) Peripheral API
* @details
* The timer module consists of three main parts:
* @li General timer config and enable control.
* @li Compare/capture control.
* @li Dead time insertion control (may not be available for all timers).
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize TIMER.
*
* @details
* Notice that counter top must be configured separately with for instance
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
* init must be initialized separately if used. That should probably
* be done prior to the use of this function if configuring the TIMER to
* start when initialization is completed.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
if (!(init->enable)) {
timer->CMD = TIMER_CMD_STOP;
}
/* Reset counter */
timer->CNT = _TIMER_CNT_RESETVALUE;
timer->CTRL = ((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT)
| ((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT)
| ((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT)
| ((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT)
| (init->debugRun ? TIMER_CTRL_DEBUGRUN : 0)
| (init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0)
| (init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0)
| (init->oneShot ? TIMER_CTRL_OSMEN : 0)
#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
| (init->count2x ? TIMER_CTRL_X2CNT : 0)
| (init->ati ? TIMER_CTRL_ATI : 0)
#endif
| (init->sync ? TIMER_CTRL_SYNC : 0);
/* Start timer if specified to be enabled (dosn't hurt if already started) */
if (init->enable) {
timer->CMD = TIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER compare/capture channel.
*
* @details
* Notice that if operating channel in compare mode, the CCV and CCVB register
* must be set separately as required.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to init for.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
EFM_ASSERT(TIMER_CH_VALID(ch));
timer->CC[ch].CTRL =
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT)
| ((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT)
| ((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT)
| ((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT)
| ((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT)
| ((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT)
| (init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0)
| (init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0)
| (init->coist ? TIMER_CC_CTRL_COIST : 0)
| (init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
}
#if defined(_TIMER_DTCTRL_MASK)
/***************************************************************************//**
* @brief
* Initialize the TIMER DTI unit.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER DTI initialization structure.
******************************************************************************/
void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init)
{
EFM_ASSERT(TIMER0 == timer);
/* Make sure the DTI unit is disabled while initializing. */
TIMER_EnableDTI(timer, false);
/* Setup the DTCTRL register.
The enable bit will be set at the end of the function if specified. */
timer->DTCTRL =
(init->autoRestart ? TIMER_DTCTRL_DTDAS : 0)
| (init->activeLowOut ? TIMER_DTCTRL_DTIPOL : 0)
| (init->invertComplementaryOut ? TIMER_DTCTRL_DTCINV : 0)
| (init->enablePrsSource ? TIMER_DTCTRL_DTPRSEN : 0)
| ((uint32_t)(init->prsSel) << _TIMER_DTCTRL_DTPRSSEL_SHIFT);
/* Setup the DTTIME register. */
timer->DTTIME =
((uint32_t)(init->prescale) << _TIMER_DTTIME_DTPRESC_SHIFT)
| ((uint32_t)(init->riseTime) << _TIMER_DTTIME_DTRISET_SHIFT)
| ((uint32_t)(init->fallTime) << _TIMER_DTTIME_DTFALLT_SHIFT);
/* Setup the DTFC register. */
timer->DTFC =
(init->enableFaultSourceCoreLockup ? TIMER_DTFC_DTLOCKUPFEN : 0)
| (init->enableFaultSourceDebugger ? TIMER_DTFC_DTDBGFEN : 0)
| (init->enableFaultSourcePrsSel0 ? TIMER_DTFC_DTPRS0FEN : 0)
| (init->enableFaultSourcePrsSel1 ? TIMER_DTFC_DTPRS1FEN : 0)
| ((uint32_t)(init->faultAction) << _TIMER_DTFC_DTFA_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel0) << _TIMER_DTFC_DTPRS0FSEL_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel1) << _TIMER_DTFC_DTPRS1FSEL_SHIFT);
/* Setup the DTOGEN register. */
timer->DTOGEN = init->outputsEnableMask;
/* Clear any previous DTI faults. */
TIMER_ClearDTIFault(timer, TIMER_GetDTIFault(timer));
/* Enable/disable before returning. */
TIMER_EnableDTI(timer, init->enable);
}
#endif
/***************************************************************************//**
* @brief
* Reset TIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Reset(TIMER_TypeDef *timer)
{
int i;
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Make sure disabled first, before resetting other registers */
timer->CMD = TIMER_CMD_STOP;
timer->CTRL = _TIMER_CTRL_RESETVALUE;
timer->IEN = _TIMER_IEN_RESETVALUE;
timer->IFC = _TIMER_IFC_MASK;
timer->TOPB = _TIMER_TOPB_RESETVALUE;
/* Write TOP after TOPB to invalidate TOPB (clear TIMER_STATUS_TOPBV) */
timer->TOP = _TIMER_TOP_RESETVALUE;
timer->CNT = _TIMER_CNT_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* (Note: ROUTE register may be locked by DTLOCK register.) */
for (i = 0; TIMER_CH_VALID(i); i++) {
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
}
/* Reset dead time insertion module, no effect on timers without DTI */
#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
/* Unlock DTI registers first in case locked */
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
timer->DTFC = _TIMER_DTFC_RESETVALUE;
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
#endif
}
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup emlib) */
#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* app.h
*
* Created on: Jun 26, 2018
* Author: conor
*/
#ifndef SRC_APP_H_
#define SRC_APP_H_
#include <stdint.h>
#define IS_BOOTLOADER
#define DEBUG_LEVEL 0
//#define PRINTING_USE_VCOM
//#define USING_DEV_BOARD
#define BRIDGE_TO_WALLET
#define JUMP_LOC 0x4000
#ifdef USING_DEV_BOARD
#define PUSH_BUTTON gpioPortF,6
#else
#define PUSH_BUTTON gpioPortD,13
#endif
//#define DISABLE_CTAPHID_PING
#define DISABLE_CTAPHID_WINK
#define DISABLE_CTAPHID_CBOR
void printing_init();
int bootloader_bridge(uint8_t klen, uint8_t * keyh);
int is_authorized_to_boot();
#define LED_INIT_VALUE 0x101000
extern uint8_t REBOOT_FLAG;
#endif /* SRC_APP_H_ */

View File

@ -1,98 +0,0 @@
/**************************************************************************//**
* @file boot.c
* @brief Functions for booting another application
* @author Silicon Labs
* @version 1.03
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_device.h"
#include "em_gpio.h"
#include "em_cmu.h"
#include "app.h"
/******************************************************************************
* This function sets up the Cortex-M3 with a new SP and PC.
*****************************************************************************/
#if defined ( __CC_ARM )
__asm void BOOT_jump(uint32_t sp, uint32_t pc)
{
/* Set new MSP, PSP based on SP (r0)*/
msr msp, r0
msr psp, r0
/* Jump to PC (r1)*/
bx r1
}
#else
void __attribute__((optimize("O0"))) BOOT_jump(uint32_t sp, uint32_t pc)
{
(void) sp;
(void) pc;
/* Set new MSP, PSP based on SP (r0)*/
__asm("msr msp, r0");
__asm("msr psp, r0");
/* Jump to PC (r1)*/
__asm("mov pc, r1");
}
#endif
/* Resets any peripherals that have been in use by
* the bootloader before booting the appliation */
static void resetPeripherals(void)
{
}
/******************************************************************************
* Boots the firmware. This function will activate the vector table
* of the firmware application and set the PC and SP from this table.
*****************************************************************************/
void __attribute__((optimize("O0"))) BOOT_boot(void)
{
uint32_t pc, sp;
uint32_t *bootAddress = (uint32_t *)(JUMP_LOC);
resetPeripherals();
/* Set new vector table */
SCB->VTOR = (uint32_t)bootAddress;
/* Read new SP and PC from vector table */
sp = bootAddress[0];
pc = bootAddress[1];
/* Do a jump by loading the PC and SP into the CPU registers */
BOOT_jump(sp, pc);
}

View File

@ -1,367 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo 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.
*
* Solo 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 Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Wrapper for crypto implementation on device
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crypto.h"
#ifdef USE_SOFTWARE_IMPLEMENTATION
#include "sha256.h"
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "device.h"
#include "app.h"
#include "log.h"
#if defined(USING_PC) || defined(IS_BOOTLOADER)
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0,
MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */
MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
} mbedtls_ecp_group_id;
#endif
const uint8_t attestation_cert_der[];
const uint16_t attestation_cert_der_size;
const uint8_t attestation_key[];
const uint16_t attestation_key_size;
static SHA256_CTX sha256_ctx;
static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = NULL;
static int _key_len = 0;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
void crypto_sha256_init()
{
sha256_init(&sha256_ctx);
}
void crypto_reset_master_secret()
{
ctap_generate_rng(master_secret, 32);
}
void crypto_sha256_update(uint8_t * data, size_t len)
{
sha256_update(&sha256_ctx, data, len);
}
void crypto_sha256_update_secret()
{
sha256_update(&sha256_ctx, master_secret, 32);
}
void crypto_sha256_final(uint8_t * hash)
{
sha256_final(&sha256_ctx, hash);
}
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x36;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
}
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x5c;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
crypto_sha256_update(hmac, 32);
crypto_sha256_final(hmac);
}
void crypto_ecc256_init()
{
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
_es256_curve = uECC_secp256r1();
}
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
_key_len = 32;
}
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
{
if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_key_len = 32;
}
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
const struct uECC_Curve_t * curve = NULL;
switch(MBEDTLS_ECP_ID)
{
case MBEDTLS_ECP_DP_SECP256R1:
curve = uECC_secp256r1();
if (_key_len != 32) goto fail;
break;
default:
printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n");
exit(1);
}
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
return;
fail:
printf2(TAG_ERR,"error, invalid key length\n");
exit(1);
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
}
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
{
uint8_t privkey[32];
uint8_t pubkey[64];
generate_private_key(data,len,NULL,0,privkey);
memset(pubkey,0,sizeof(pubkey));
uECC_compute_public_key(privkey, pubkey, _es256_curve);
memmove(x,pubkey,32);
memmove(y,pubkey+32,32);
}
void crypto_load_external_key(uint8_t * key, int len)
{
_signing_key = key;
_key_len = len;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_make_key failed\n");
exit(1);
}
}
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
{
if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_shared_secret failed\n");
exit(1);
}
}
struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
{
if (key == CRYPTO_TRANSPORT_KEY)
{
AES_init_ctx(&aes_ctx, transport_secret);
}
else
{
AES_init_ctx(&aes_ctx, key);
}
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
// prevent round key recomputation
void crypto_aes256_reset_iv(uint8_t * nonce)
{
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
void crypto_aes256_decrypt(uint8_t * buf, int length)
{
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
}
void crypto_aes256_encrypt(uint8_t * buf, int length)
{
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}
const uint8_t attestation_cert_der[] =
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
const uint16_t attestation_key_size = sizeof(attestation_key)-1;
#else
#error "No crypto implementation defined"
#endif

Some files were not shown because too many files have changed in this diff Show More