first commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.pio
|
||||
|
||||
.idea
|
||||
39
include/README
Normal file
39
include/README
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
504
lib/Arduino_MFRC522v2-master/LICENSE
Normal file
504
lib/Arduino_MFRC522v2-master/LICENSE
Normal file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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 Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
296
lib/Arduino_MFRC522v2-master/README.md
Normal file
296
lib/Arduino_MFRC522v2-master/README.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Arduino_MFRC522v2
|
||||
|
||||
[](#development)
|
||||
[](https://github.com/OSSLibraries/Arduino_MFRC522v2/actions/workflows/test.arduino-compile-examples.yml)
|
||||
[](https://github.com/OSSLibraries/Arduino_MFRC522v2/actions/workflows/test.arduino-lint.yml)
|
||||
[](#compatible-ide)
|
||||
[](https://github.com/OSSLibraries/Arduino_MFRC522v2/releases)
|
||||
[](#compatible-ide)
|
||||
|
||||
Advanced Arduino driver library for MFRC522 and other RFID RC522 based modules.
|
||||
|
||||
Read and write different types of **R**adio-**F**requency **ID**entification (RFID) cards on your Arduino using a RC522 based reader connected via the Serial Peripheral Interface (SPI) or I2C interface.
|
||||
|
||||
## Hints for this version
|
||||
|
||||
* Fork of <https://github.com/miguelbalboa/rfid/>
|
||||
* Changed license to GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1.
|
||||
* Target group are experienced makers.
|
||||
* Code was heavily split up for better maintenance.
|
||||
* Hardware interface is fully customisable.
|
||||
* Use of software reset. No reset pin.
|
||||
* Some parts were removed.
|
||||
|
||||
## Development
|
||||
|
||||
**Feature status: open**; focus on rfid; no applications;
|
||||
|
||||
**Code status: open**; fixes/typos or documentation updates; *no* specific code for other boards; *avoid* examples;
|
||||
|
||||
**Maintenance status: sporadically**;
|
||||
|
||||
## Before buy
|
||||
|
||||
Please notice that there are many sellers (ebay, aliexpress, ...) who sell MFRC522 boards.
|
||||
**The quality of these boards are extremely different.**
|
||||
Some are soldered with wrong/low quality capacitors or fake/defect MFRC522.
|
||||
|
||||
**Please consider buying several devices from different suppliers.**
|
||||
So the chance of getting a working device is higher.
|
||||
|
||||
If you got a bad board and you can tell us how to detect those boards (silk, chip description, ...), please share your knowledge.
|
||||
|
||||
## What works and not?
|
||||
|
||||
* **Works**
|
||||
|
||||
* Communication (Crypto1) with MIFARE Classic (1k, 4k, Mini).
|
||||
* Communication (Crypto1) with MIFARE Classic compatible PICCs.
|
||||
* Firmware self check of MFRC522.
|
||||
* Set the UID, write to sector 0, and unbrick Chinese UID changeable MIFARE cards.
|
||||
* Manage the SPI chip select pin (aka SS, SDA):
|
||||
|
||||
* **Works partially**
|
||||
|
||||
* Communication with MIFARE Ultralight.
|
||||
* Other PICCs (Ntag216).
|
||||
* More than 2 modules, require a multiplexer [#191](https://github.com/miguelbalboa/rfid/issues/191#issuecomment-242631153).
|
||||
|
||||
* **Doesn't work**
|
||||
|
||||
* MIFARE DESFire, MIFARE DESFire EV1/EV2, not supported by software.
|
||||
* Communication with 3DES or AES, not supported by software.
|
||||
* Peer-to-peer (ISO/IEC 18092), not [supported by hardware](https://web.archive.org/web/20151210045625/http://www.nxp.com/documents/leaflet/939775017564.pdf).
|
||||
* Communication with smartphone, not [supported by hardware](https://web.archive.org/web/20151210045625/http://www.nxp.com/documents/leaflet/939775017564.pdf).
|
||||
* Card emulation, not [supported by hardware](https://web.archive.org/web/20151210045625/http://www.nxp.com/documents/leaflet/939775017564.pdf).
|
||||
* Use of IRQ pin. But there is a proof-of-concept example.
|
||||
* With Intel Galileo (Gen2) see [#310](https://github.com/miguelbalboa/rfid/issues/310), not supported by software.
|
||||
* Power reduction modes [#269](https://github.com/miguelbalboa/rfid/issues/269), not supported by software.
|
||||
* UART instead of SPI [#281](https://github.com/miguelbalboa/rfid/issues/281), not supported by software.
|
||||
|
||||
* **Need more?**
|
||||
|
||||
* If software: code it and make a pull request.
|
||||
* If hardware: buy a more expensive like PN532 (supports NFC and many more, but costs about $15 and not usable with this library).
|
||||
|
||||
## Compatible IDE
|
||||
|
||||
This library works with Arduino IDE 1.6, older versions are **not supported** and will cause compiler errors. The built-in library manager is supported.
|
||||
|
||||
If you use your own compiler, you have to enable `c++11`-support.
|
||||
|
||||
## Compatible boards
|
||||
|
||||
This library is compatible with boards implementing the [Arduino-API](https://github.com/arduino/ArduinoCore-API). You also have to change pins. See [pin layout](#pin-layout).
|
||||
|
||||
Some user made some patches/suggestions/ports for other boards:
|
||||
|
||||
* Linux: <https://github.com/miguelbalboa/rfid/pull/216>
|
||||
* chipKIT: <https://github.com/miguelbalboa/rfid/pull/230>
|
||||
* ESP8266 (native): <https://github.com/miguelbalboa/rfid/pull/235>
|
||||
* LPCOPen (in C): <https://github.com/miguelbalboa/rfid/pull/258>
|
||||
|
||||
## Support/issue
|
||||
|
||||
1. First checkout [what works and not](#what-works-and-not) and [troubleshooting](#troubleshooting) .
|
||||
|
||||
2. It seems to be a hardware issue or you need support to program your project?
|
||||
Please ask in the official [Arduino forum](https://forum.arduino.cc), where you would get a much faster answer than on GitHub.
|
||||
|
||||
3. It seems to be a software issue?
|
||||
Open an issue on GitHub.
|
||||
|
||||
## Code style
|
||||
|
||||
Please use `fixed integers`, see [stdint.h](https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdint.h).
|
||||
Why? This library is compatible with different boards which use different architectures (16bit and 32bit).
|
||||
Unfixed `int` variables have different sizes in different environments and may cause unpredictable behaviour.
|
||||
|
||||
## Pin Layout
|
||||
|
||||
The following tables show the typical pin layout used.
|
||||
|
||||
Notes:
|
||||
|
||||
* The SDA pin on the MFRC522 might be labeled as SS.
|
||||
* `RST` pin of the microcontroller-board is configurable, typically defined as `RST_PIN` in sketch/program.
|
||||
* `SDA` pin of the microcontroller-board is configurable, typically defined as `SS_PIN` in sketch/program.
|
||||
* Important: If your microcontroller supports multiple SPI interfaces, the library only uses the **default (first) SPI** of the Arduino framework.
|
||||
|
||||
### Arduino
|
||||
|
||||
| Signal | MFRC522 | Uno / 101 | Mega | Nano v3 | Leonardo / Micro | Pro Micro | Yun |
|
||||
|:----------|:--------|------------:|-----:|--------:|-----------------:|----------:|------:|
|
||||
| RST/Reset | RST | 9 | 5 | D9 | RESET / ICSP-5 | RST | Pin9 |
|
||||
| SPI SS | SDA | 10 | 53 | D10 | 10 | 10 | Pin10 |
|
||||
| SPI MOSI | MOSI | 11 / ICSP-4 | 51 | D11 | ICSP-4 | 16 | ICSP4 |
|
||||
| SPI MISO | MISO | 12 / ICSP-1 | 50 | D12 | ICSP-1 | 14 | ICSP1 |
|
||||
| SPI SCK | SCK | 13 / ICSP-3 | 52 | D13 | ICSP-3 | 15 | ICSP3 |
|
||||
|
||||
### ESP8266
|
||||
|
||||
| Signal | MFRC522 | Wemos D1 mini |
|
||||
|:----------|:--------|--------------:|
|
||||
| RST/Reset | RST | D3 |
|
||||
| SPI SS | SDA | D8 |
|
||||
| SPI MOSI | MOSI | D7 |
|
||||
| SPI MISO | MISO | D6 |
|
||||
| SPI SCK | SCK | D5 |
|
||||
|
||||
### ESP32
|
||||
|
||||
| Signal | MFRC522 | WROOM-32 |
|
||||
|:----------|:--------|---------:|
|
||||
| RST/Reset | RST | 21 |
|
||||
| SPI SS | SDA | 5 |
|
||||
| SPI MOSI | MOSI | 23 |
|
||||
| SPI MISO | MISO | 19 |
|
||||
| SPI SCK | SCK | 18 |
|
||||
|
||||
### Teensy
|
||||
|
||||
| Signal | MFRC522 | 2.0 | ++2.0 | 3.1 |
|
||||
|:----------|:--------|----:|------:|----:|
|
||||
| RST/Reset | RST | 7 | 4 | 9 |
|
||||
| SPI SS | SDA | 0 | 20 | 10 |
|
||||
| SPI MOSI | MOSI | 2 | 22 | 11 |
|
||||
| SPI MISO | MISO | 3 | 23 | 12 |
|
||||
| SPI SCK | SCK | 1 | 21 | 13 |
|
||||
|
||||
## Hardware
|
||||
|
||||
There are three hardware components involved:
|
||||
|
||||
* **Microcontroller**
|
||||
|
||||
* An [Arduino](https://arduino.cc/) or compatible executing the Sketch using this library.
|
||||
* Prices vary from USD 7 for clones, to USD 75 for "starter kits" (which might be a good choice if this is your first exposure to Arduino; check if such kit already includes the Arduino, Reader, and some Tags).
|
||||
|
||||
* **Proximity Coupling Device (PCD)**
|
||||
|
||||
* The PCD is the actual RFID **Reader** based on the [NXP MFRC522](https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf) Contactless Reader Integrated Circuit.
|
||||
* Readers can be found on many online stores for around USD 5: search for *"rc522"*.
|
||||
* You can also find them on several web stores. They are often included in *"starter kits"*, so check your favourite electronics provider as well.
|
||||
|
||||
* **Proximity Integrated Circuit Card (PICC)**
|
||||
|
||||
* The PICC is the RFID **Card** or **Tag** using the [ISO/IEC 14443A](https://en.wikipedia.org/wiki/ISO/IEC_14443) interface, for example Mifare or NTAG203.
|
||||
* One or two might be included with the Reader or *"starter kit"* already.
|
||||
|
||||
## Protocols
|
||||
|
||||
* The microcontroller and the reader use SPI for communication.
|
||||
* The protocol is described in the [NXP MFRC522](https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf) datasheet.
|
||||
* See the [Pin Layout](#pin-layout) section for details on connecting the pins.
|
||||
|
||||
* The reader and the tags communicate using a 13.56 MHz electromagnetic field.
|
||||
* The protocol is defined in ISO/IEC 14443-3:2011 Part 3 Type A.
|
||||
* Details are found in chapter 6 *"Type A – Initialization and anticollision"*.
|
||||
* See <https://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf> for a free version of the final draft (which might be outdated in some areas).
|
||||
* The reader does not support ISO/IEC 14443-3 Type B.
|
||||
|
||||
## Security
|
||||
|
||||
* The **UID** of a card **can not be used** as a unique identification for security related projects.
|
||||
Some Chinese cards allow to change the UID which means you can easily clone a card.
|
||||
For projects like *access control*, *door opener* or *payment systems* you **must implement** an **additional security mechanism** like a password or normal key.
|
||||
|
||||
* This library only supports `crypto1`-encrypted communication. `Crypto1` has been known as [broken](https://eprint.iacr.org/2008/166) for a few years, so it does NOT offer ANY security, it is virtually unencrypted communication.
|
||||
**Do not use it for any security related applications!**
|
||||
|
||||
* This library does not offer 3DES or AES authentication used by cards like the Mifare DESFire, it may be possible to be implemented because the datasheet says there is support. We hope for pull requests :).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* **I don't get input from reader** or **WARNING: Communication failure, is the MFRC522 properly connected?**
|
||||
|
||||
* Check your physical connection, see [Pin Layout](#pin-layout).
|
||||
* Check your pin settings/variables in the code, see [Pin Layout](#pin-layout).
|
||||
* Check your pin header soldering. Maybe you have cold solder joints.
|
||||
* Check voltage. Most breakouts work with 3.3V.
|
||||
* SPI only works with 3.3V, most breakouts seem 5V tolerant, but try a level shifter.
|
||||
* SPI does not like long connections. Try shorter connections.
|
||||
* SPI does not like prototyping boards. Try soldered connections.
|
||||
* According to reports #101, #126 and #131, there may be a problem with the soldering on the MFRC522 breakout. You could fix this on your own.
|
||||
|
||||
|
||||
* **Firmware Version: 0x12 = (unknown) or other random values**.
|
||||
|
||||
* The exact reason of this behaviour is unknown.
|
||||
* Some boards need more time after `PCD_Init()` to be ready. As workaround add a `delay(4)` directly after `PCD_Init()` to give the PCD more time.
|
||||
* If this sometimes appears, a bad connection or power source is the reason.
|
||||
* If the firmware version is reported permanent, it is very likely that the hardware is a fake or has a defect. Contact your supplier.
|
||||
|
||||
|
||||
* **Sometimes I get timeouts** or **sometimes tag/card does not work.**
|
||||
|
||||
* Try the other side of the antenna.
|
||||
* Try to decrease the distance between the MFRC522 and your tag.
|
||||
* Increase the antenna gain per firmware: `MFRC522.PCD_SetAntennaGain(MFRC522.RxGain_max);`.
|
||||
* Use better power supply.
|
||||
* Hardware may be corrupted, most products are from China and sometimes the quality is really poor. Contact your seller.
|
||||
|
||||
|
||||
* **My tag/card doesn't work.**
|
||||
|
||||
* Distance between antenna and token too large (>1cm).
|
||||
* You got the wrong type PICC. Is it really 13.56 MHz? Is it really a Mifare Type A?
|
||||
* NFC tokens are not supported. Some may work.
|
||||
* Animal RFID tags are not supported. They use a different frequency (125 kHz).
|
||||
* Hardware may be corrupted, most products are from China and sometimes the quality is really poor. Contact your seller.
|
||||
* Newer versions of Mifare cards like DESFire/Ultralight maybe not work according to missing authentication, see [security](#security) or different [protocol](#protocols).
|
||||
* Some boards bought from Chinese manufactures do not use the best components and this can affect the detection of different types of tag/card.
|
||||
In some of these boards, the L1 and L2 inductors do not have a high enough current so the signal generated is not enough to get Ultralight C and NTAG203 tags to work, replacing those with same inductance (2.2uH) but higher operating current inductors should make things work smoothly.
|
||||
Also, in some of those boards the harmonic and matching circuit needs to be tuned, for this replace C4 and C5 with 33pf capacitors and you are all set.
|
||||
(Source: [Mikro Elektronika](https://forum.mikroe.com/viewtopic.php?f=147&t=64203))
|
||||
|
||||
* **My mobile phone doesn't recognize the MFRC522** or **my MFRC522 can't read data from other MFRC522**.
|
||||
|
||||
* Card simulation is not supported.
|
||||
* Communication with mobile phones is not supported.
|
||||
* Peer to peer communication is not supported.
|
||||
|
||||
* **I can only read the card UID.**
|
||||
|
||||
* Maybe the `AccessBits` have been accidentally set and now an unknown password is set. This can not be reverted.
|
||||
* Probably the card is encrypted. Especially official cards like public transport, university or library cards. There is *no* way to get access with this library.
|
||||
|
||||
* **I need more features.**
|
||||
|
||||
* If software: code it and make a pull request.
|
||||
* If hardware: buy a more expensive chip like the `PN532` (supports NFC and many more, but costs about $15).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1.
|
||||
|
||||
It is not allowed to change the license.
|
||||
|
||||
## Dependency
|
||||
|
||||
* **Arduino.h**
|
||||
|
||||
* From: Arduino IDE / target specific
|
||||
* License: (target: Arduino) GNU Lesser General Public License 2.1
|
||||
|
||||
* **SPI.h**
|
||||
|
||||
* From: Arduino IDE / target specific
|
||||
* License: (target: Arduino) GNU Lesser General Public License 2.1
|
||||
|
||||
* **stdint.h**
|
||||
|
||||
* From: Arduino IDE / Compiler and target specific
|
||||
* License: different
|
||||
|
||||
## History
|
||||
|
||||
The MFRC522 library was first created in Jan 2012 by Miguel Balboa (from <http://circuitito.com>) based on code by Dr. Leong (from <http://B2CQSHOP.com>) for *"Arduino RFID module Kit 13.56 Mhz with Tags SPI W and R By COOQRobot"*.
|
||||
|
||||
It was translated into English and rewritten/refactored in the fall of 2013 by Søren Thing Andersen (from <http://access.thing.dk>).
|
||||
|
||||
It has been extended with functionality to alter sector 0 on Chinese UID changeable MIFARE card in Oct 2014 by Tom Clement (from <http://tomclement.nl>).
|
||||
|
||||
Maintained by miguelbalboa until 2016.
|
||||
Maintained by Rotzbua from 2016 until 2022.
|
||||
219
lib/Arduino_MFRC522v2-master/changes.txt
Normal file
219
lib/Arduino_MFRC522v2-master/changes.txt
Normal file
@@ -0,0 +1,219 @@
|
||||
-- Add changes to unreleased tag until we make a release.
|
||||
|
||||
xx xx 202x, v2.0.7
|
||||
|
||||
25 Dec 2024, v2.0.6
|
||||
- Re-release broken v2.0.5
|
||||
|
||||
08 Aug 2024, v2.0.5
|
||||
- Remove deprecation, fix problem with ESP32 @PBrunot
|
||||
- Update documentation dependencies
|
||||
|
||||
19 Oct 2022, v2.0.4
|
||||
- More clones from FudanMicro
|
||||
- Fritzing: fixed crossed wires
|
||||
|
||||
28 Oct 2021, v2.0.3
|
||||
- Fix library.properties
|
||||
|
||||
28 Oct 2021, v2.0.2
|
||||
|
||||
- Fix self-test.
|
||||
- Add UID print.
|
||||
|
||||
30 Dec 2020, v2.0.1
|
||||
- Fixed wrong SPI clock speed.
|
||||
|
||||
25 Jun 2020, v2.0.0
|
||||
- Changed license to GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1.
|
||||
- Target group are experienced makers.
|
||||
- Code was heavily split up for better maintenance.
|
||||
- Hardware interface is fully customisable. Use MFRC522Driver.h.
|
||||
- Use of software reset. No reset pin.
|
||||
- Removed many examples, focus on basic function
|
||||
|
||||
25 Jun 2020, v1.4.7
|
||||
- Fixed typos
|
||||
- Moved PICC memory layout to /doc
|
||||
|
||||
25 Jun 2020, v1.4.7
|
||||
- Fixed typos
|
||||
- Moved PICC memory layout to /doc
|
||||
|
||||
21 Jan 2020, v1.4.6
|
||||
- Library in freeze mode, no new features, no new examples, just bugfixes to keep compatibility for old projects
|
||||
- Updated documentation
|
||||
- Removed deprecation warnings due code freeze
|
||||
|
||||
12 Jun 2019, v1.4.5
|
||||
- Library in freeze mode, no new features, no new examples, just bugfixes to keep compatibility for old projects
|
||||
- Updated README
|
||||
|
||||
31 Mar 2019, v1.4.4
|
||||
- Fixed example
|
||||
- Fixed UnbrickUidSector
|
||||
- Updated comments
|
||||
- Removed teensy from CI and PlatformIO config
|
||||
|
||||
27 Oct 2018, v1.4.3
|
||||
- Added counterfeit detection and hint about bad boards
|
||||
- Improved hardware based reset
|
||||
|
||||
04 Oct 2018, v1.4.2
|
||||
- Fixed keywords
|
||||
- Changed development status of library
|
||||
|
||||
04 Oct 2018, v1.4.1
|
||||
- Replaced UINT8_MAX by UNUSED_PIN
|
||||
- Replaced default value NULL for pointer with correct nullptr
|
||||
- Added pin layout for wemos d1 mini @mmone
|
||||
- Added alternative fritzing layout for mfrc522 reader @jose1711
|
||||
- Added soft power control functions @Bill2462
|
||||
- Fixed typo in example ReadAndWrite.ino @Drachenfrucht1
|
||||
- Fixed grammar @KiddieD
|
||||
- Fixed infinite loop in example AccessControl.ino @mads256c
|
||||
- Fixed 0-index key ID equals to 0 fails in AccessControl.ino @thoaitrieu
|
||||
- Changed type boolean to bool for a more common use @Rotzbua
|
||||
- Fixed wrong var names in PICC_Select MFRC522.cpp @tuyethoa08041997
|
||||
- Fixed hang PCD_Init() on non-arduino boards @heziegl
|
||||
- Fixed possible infinite loop PCD_Reset() @psgreco
|
||||
- And many thanks to all other contributors
|
||||
|
||||
13 Apr 2018, v1.4.0
|
||||
- Replaced UINT8_MAX by UNUSED_PIN @Rotzbua
|
||||
- Fixed hang PCD_Init() on non-arduino boards @heziegl
|
||||
- deprecate MIFARE_SetAccessBits @Rotzbua
|
||||
- IMPORTANT: v1.4.X will be last version under license "unlicense"
|
||||
|
||||
22 Mar 2017, v1.3.6
|
||||
- Added deprecate and compiler warnings @Rotzbua
|
||||
|
||||
8 Apr 2017, v1.3.5
|
||||
- Updated "AccessControl.ino", bugs fixed and alternate wipe button polling method without using other library @beyondszine reviewed by @omersiar
|
||||
- Updated README notice about port for esp8266 @mmmmar
|
||||
|
||||
7 Apr 2017, v1.3.4
|
||||
- Added new example "rfid_read_personal_data.ino" @ryand1011
|
||||
- Updated example "rfid_write_personal_data.ino" code style to Arduino IDE @Rotzbua
|
||||
- Removed (temp.) Teensy from travis build script because fails @Rotzbua
|
||||
|
||||
26 Mar 2017, v1.3.3
|
||||
- Fixed bugs in MFRC522Extended, now should work with Desfire.h from JPG-Consulting @Rotzbua
|
||||
- Fixed UINT8_MAX error @Rotzbua
|
||||
|
||||
15 Mar 2017, v1.3.2
|
||||
- Added ESP8266 to library.properties
|
||||
|
||||
15 Mar 2017, v1.3.1
|
||||
- Fixed compiler warning in MFRC522Extended @Rotzbua
|
||||
- Removed unused function @Rotzbua
|
||||
|
||||
13 Mar 2017, v1.3.0
|
||||
- Warning: Source has moved to folder src!
|
||||
- Added additional class to support ISO/IEC 14443-4 PICCs @JPG-Consulting
|
||||
- Added RATS (Request for Answer To Select) @JPG-Consulting
|
||||
- More information see https://github.com/miguelbalboa/rfid/pull/271 @JPG-Consulting
|
||||
|
||||
13 Mar 2017, v1.2.1
|
||||
- Removed need for reset pin #275 @tkoester
|
||||
- Added SPI speed option + Various minor changes #276 @tuyethoa08041997
|
||||
- Updated documentation, travis build script and small code change @Rotzbua
|
||||
|
||||
3 Jan 2017, v1.2.0
|
||||
- Warning: This version introduce usage of stdint.h, usage of not well defined int types are abandoned.
|
||||
Interface has changed: e.g. long -> int32_t
|
||||
@Rotzbua
|
||||
- Removed problematic example examples/servo_motor/servo_motor.ino @omersiar
|
||||
- Added examples/AccessControl/AccessControl.ino @omersiar
|
||||
- Fixed minor issues reported in #211 @omersiar
|
||||
- Added bad components hint to README @danielcbit
|
||||
- Fixed selftest @surr
|
||||
- Fixed auth problem with long UIDs @surr
|
||||
|
||||
26 Aug 2016, v1.1.9
|
||||
- Warning: Only Arduino IDE version 1.6 is supported, please update your IDE to 1.6 to use this Library.
|
||||
- Added ESP8266 platform support @Rotzbua
|
||||
- Changed README.rst content to show more info @Rotzbua
|
||||
- Minor Changes to examples/ReadUidMultiReader/ReadUidMultiReader.ino example @Rotzbua
|
||||
|
||||
11 Feb 2016, v1.1.8
|
||||
- Added examples/MinimalInterrupt/MinimalInterrupt.ino example, Interrupt example @lmmeng
|
||||
- Added .gitignore file allows the project to be more easily used as a subproject. @BenWiederhake
|
||||
- Added Added Teensy 2.0 & Tensy++ 2.0 pinouts to README.rst @jkutianski
|
||||
|
||||
16 Jan 2016, v1.1.7
|
||||
- README.rst Spelling and Grammar Tweak @cuthbertnibbles
|
||||
- Added examples/servo_motor/servo_motor.ino example, Arduino RFID Access Control with a Servo Motor @techied
|
||||
- Added examples/RFID-Cloner/RFID-Cloner.ino Copy from rfid cards with standard authentication @stefanblommaert
|
||||
- Fix compile error at examples/RFID-Cloner/RFID-Cloner.ino, using MFRC522:::PICC_Type, @Rotzbua
|
||||
|
||||
06 Jan 2016, v1.1.6
|
||||
- Fixed compilation error for examples/ReadNUID/ReadNUID.ino example. @Rotzbua
|
||||
|
||||
04 Jan 2016, v1.1.5
|
||||
- Use settings functions on SPI libraries, setSPIConfig was deleted, now the library use SPI.beginTransaction() and SPI.endTransaction() @sophiekovalevsky
|
||||
- Added examples/ReadNUID/ReadNUID.ino example, showing how to read new NUID from a PICC to serial. @sophiekovalevsky
|
||||
|
||||
03 Jan 2016, v1.1.4
|
||||
- Added Authentication with Ntag 213,215,216 returns the pACK MFRC522::PCD_NTAG216_AUTH @Gargantuanman
|
||||
- Starting to use versions http://semver.org/
|
||||
- Continuous Integration @ivankravets
|
||||
- functions return MFRC522::StatusCode and MFRC522::PICC_Type instead of generic byte @rotzbua
|
||||
- removed int-values of MFRC522::StatusCode and MFRC522::PICC_Type @rotzbua
|
||||
|
||||
05 Dec 2015
|
||||
- recognize infineon cards correctly @mayatforest
|
||||
- added multi reader support, see example @lmmeng
|
||||
|
||||
10 Nov 2014
|
||||
- Updated the changelog.
|
||||
- Added makefile.
|
||||
|
||||
24 Oct 2014
|
||||
- Added PlatformIO-based manifest file.
|
||||
|
||||
17 Jul 2014
|
||||
- Written documentation for the library.
|
||||
- Added rfid_default_keys example.
|
||||
|
||||
11 Jun 2014
|
||||
- Updated example: ReadAndWrite.
|
||||
|
||||
14 Apr 2014
|
||||
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
|
||||
|
||||
12 Feb 2014
|
||||
- Fixed resetPowerDownPin initial state.
|
||||
|
||||
29 Jan 2014
|
||||
- Fixed chipSelectPin initial state.
|
||||
|
||||
30 Nov 2013
|
||||
- Examples put in their own folders.
|
||||
- Updated the keywords.txt file.
|
||||
|
||||
12 Nov 2013
|
||||
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
|
||||
|
||||
20 Oct 2013
|
||||
- All constants, functions and parameters are now commented in English.
|
||||
- Code refactored, most function names have changed.
|
||||
- Support ISO-14443-3 anti collision and 4/7/10 byte UIDs (cascade levels).
|
||||
- Added functions for MIFARE Classic Decrement/Increment/Restore/Transfer
|
||||
and MIFARE Ultralight Write.
|
||||
- New examples written.
|
||||
|
||||
19 Oct 2013
|
||||
- Renamed library from RFID to MFRC522 (RFID seemed to generic).
|
||||
- Register names changed to comply with datasheet.
|
||||
- Global defines moved into class.
|
||||
|
||||
24 Sep 2013
|
||||
- Turn off encryption when tag is halted.
|
||||
|
||||
27 Jan 2013
|
||||
- Added README and small TODO list.
|
||||
- Added example to show Serial on LCD display.
|
||||
|
||||
09 Sep 2012
|
||||
- Initial commit to GitHub.
|
||||
20
lib/Arduino_MFRC522v2-master/doc/Makefile
Normal file
20
lib/Arduino_MFRC522v2-master/doc/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = src
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
79
lib/Arduino_MFRC522v2-master/doc/PICCMemoryLayout.md
Normal file
79
lib/Arduino_MFRC522v2-master/doc/PICCMemoryLayout.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Memory Layout of common PICCs
|
||||
|
||||
To read and write from MIFARE PICCs, the MIFARE protocol is used after the PICC has been selected.
|
||||
|
||||
## Datasheet References
|
||||
|
||||
The **MIFARE Classic** chips and protocol is described in the datasheets:
|
||||
|
||||
* 1K: https://www.mouser.com/ds/2/302/MF1S503x-89574.pdf
|
||||
* 4K: https://datasheet.octopart.com/MF1S7035DA4,118-NXP-Semiconductors-datasheet-11046188.pdf
|
||||
* Mini: http://www.idcardmarket.com/download/mifare_S20_datasheet.pdf
|
||||
|
||||
The **MIFARE Ultralight** chip and protocol is described in the datasheets:
|
||||
|
||||
* Ultralight: https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
|
||||
* Ultralight C: https://www.nxp.com/documents/short_data_sheet/MF0ICU2_SDS.pdf
|
||||
|
||||
## MIFARE Classic 1K (MF1S503x)
|
||||
|
||||
Has 16 sectors4 blocks/sector16 bytes/block = 1024 bytes.
|
||||
|
||||
```text
|
||||
The blocks are numbered 0-63.
|
||||
Block 3 in each sector is the Sector Trailer. See https://www.mouser.com/ds/2/302/MF1S503x-89574.pdf sections 8.6 and 8.7:
|
||||
Bytes 0-5: Key A
|
||||
Bytes 6-8: Access Bits
|
||||
Bytes 9: User data
|
||||
Bytes 10-15: Key B (or user data)
|
||||
Block 0 is read-only manufacturer data.
|
||||
To access a block, an authentication using a key from the block's sector must be performed first.
|
||||
Example: To read from block 10, first authenticate using a key from sector 3 (blocks 8-11).
|
||||
All keys are set to FFFFFFFFFFFFh at chip delivery.
|
||||
Warning: Please read section 8.7 "Memory Access". It includes this text: if the PICC detects a format violation the whole sector is irreversibly blocked.
|
||||
To use a block in "value block" mode (for Increment/Decrement operations) you need to change the sector trailer. Use PICC_SetAccessBits() to calculate the bit patterns.
|
||||
```
|
||||
|
||||
## MIFARE Classic 4K (MF1S703x)
|
||||
|
||||
Has (32 sectors4 blocks/sector + 8 sectors16 blocks/sector)16 bytes/block = 4096 bytes.
|
||||
|
||||
```text
|
||||
The blocks are numbered 0-255.
|
||||
The last block in each sector is the Sector Trailer like above.
|
||||
```
|
||||
|
||||
## MIFARE Classic Mini (MF1 IC S20)
|
||||
|
||||
Has 5 sectors4 blocks/sector16 bytes/block = 320 bytes.
|
||||
|
||||
```text
|
||||
The blocks are numbered 0-19.
|
||||
The last block in each sector is the Sector Trailer like above.
|
||||
```
|
||||
|
||||
## MIFARE Ultralight (MF0ICU1)
|
||||
|
||||
Has 16 pages of 4 bytes = 64 bytes.
|
||||
|
||||
```text
|
||||
Pages 0 + 1 is used for the 7-byte UID.
|
||||
Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
||||
Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
||||
Pages 4-15 are read/write unless blocked by the lock bytes in page 2.
|
||||
```
|
||||
|
||||
## MIFARE Ultralight C (MF0ICU2)
|
||||
|
||||
Has 48 pages of 4 bytes = 192 bytes.
|
||||
|
||||
```text
|
||||
Pages 0 + 1 is used for the 7-byte UID.
|
||||
Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
||||
Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
||||
Pages 4-39 are read/write unless blocked by the lock bytes in page 2.
|
||||
Page 40 Lock bytes
|
||||
Page 41 16 bit one way counter
|
||||
Pages 42-43 Authentication configuration
|
||||
Pages 44-47 Authentication key
|
||||
```
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 343 KiB |
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522 - Pin Layout.png
Executable file
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522 - Pin Layout.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
Binary file not shown.
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v2.png
Normal file
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
Binary file not shown.
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v3.png
Normal file
BIN
lib/Arduino_MFRC522v2-master/doc/fritzing/RFID-RC522-v3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
35
lib/Arduino_MFRC522v2-master/doc/make.bat
Normal file
35
lib/Arduino_MFRC522v2-master/doc/make.bat
Normal file
@@ -0,0 +1,35 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=src
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
6
lib/Arduino_MFRC522v2-master/doc/requirements.txt
Normal file
6
lib/Arduino_MFRC522v2-master/doc/requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
breathe==4.36.0
|
||||
exhale==0.3.7
|
||||
myst-parser==4.0.1
|
||||
myst-parser[linkify]
|
||||
sphinx==8.2.1
|
||||
sphinx-notfound-page==1.1.0
|
||||
BIN
lib/Arduino_MFRC522v2-master/doc/rfidmifare.pdf
Normal file
BIN
lib/Arduino_MFRC522v2-master/doc/rfidmifare.pdf
Normal file
Binary file not shown.
11
lib/Arduino_MFRC522v2-master/doc/src/Doxyfile
Normal file
11
lib/Arduino_MFRC522v2-master/doc/src/Doxyfile
Normal file
@@ -0,0 +1,11 @@
|
||||
PROJECT_NAME = "MFRC522"
|
||||
INPUT = "../../src"
|
||||
|
||||
OUTPUT_DIRECTORY = "./_doxygen"
|
||||
EXTRACT_ALL = NO # YES
|
||||
EXTRACT_PRIVATE = NO # YES
|
||||
RECURSIVE = YES
|
||||
VERBATIM_HEADERS = NO
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_XML = YES
|
||||
86
lib/Arduino_MFRC522v2-master/doc/src/conf.py
Normal file
86
lib/Arduino_MFRC522v2-master/doc/src/conf.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
sys.path.append(os.path.abspath('../..'))
|
||||
|
||||
# Create xml data by Doxygen for sphinx.
|
||||
subprocess.call('doxygen Doxyfile', shell=True)
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'RFID_MFRC522v2'
|
||||
copyright = '2023, GithubCommunity'
|
||||
author = 'GithubCommunity'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = [
|
||||
'breathe',
|
||||
"exhale",
|
||||
'myst_parser',
|
||||
'notfound.extension',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.githubpages',
|
||||
'sphinx.ext.ifconfig',
|
||||
'sphinx.ext.inheritance_diagram',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = ['Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
source_suffix = {
|
||||
'.rst': 'restructuredtext',
|
||||
'.txt': 'literal',
|
||||
'.md': 'markdown',
|
||||
}
|
||||
|
||||
# If this is not None, a ‘Last updated on:’ timestamp is inserted at every page bottom.
|
||||
html_last_updated_fmt = ''
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
#html_theme = 'alabaster'
|
||||
html_theme = 'nature'
|
||||
html_static_path = ['_static']
|
||||
|
||||
### Custom plugins ###
|
||||
## Markdown
|
||||
myst_enable_extensions = [
|
||||
"linkify",
|
||||
"smartquotes",
|
||||
"strikethrough",
|
||||
"tasklist",
|
||||
]
|
||||
## Bridge doxygen <> sphinx.
|
||||
breathe_projects = {
|
||||
'MFRC522': "./_doxygen/xml/"
|
||||
}
|
||||
breathe_default_project = 'MFRC522'
|
||||
breathe_default_members = (
|
||||
'members',
|
||||
# 'undoc-members',
|
||||
)
|
||||
## Auto generate doc for every cpp-file.
|
||||
exhale_args = {
|
||||
"containmentFolder": "./lib",
|
||||
"doxygenStripFromPath": "..",
|
||||
"rootFileName": "index.rst",
|
||||
"rootFileTitle": "Library API",
|
||||
# "createTreeView": True,
|
||||
}
|
||||
|
||||
38
lib/Arduino_MFRC522v2-master/doc/src/index.rst
Normal file
38
lib/Arduino_MFRC522v2-master/doc/src/index.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
.. include:: ../../README.rst
|
||||
|
||||
Library documentation
|
||||
=====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
lib/index.rst
|
||||
|
||||
PICC
|
||||
====
|
||||
|
||||
.. include:: ../PICCMemoryLayout.md
|
||||
:parser: myst_parser.sphinx_
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
.. include:: ../../changes.txt
|
||||
:literal:
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
.. include:: ../../LICENSE
|
||||
:literal:
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example to test your firmware.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* This example test the firmware of your MFRC522 reader module, only known version can be checked. If the test passed
|
||||
* it do not mean that your module is faultless! Some modules have bad or broken antennas or the PICC is broken.
|
||||
*
|
||||
* @author Rotzbua
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
//#include <MFRC522DriverI2C.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_pin(10); // Configurable, see typical pin layout above.
|
||||
|
||||
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver.
|
||||
//MFRC522DriverI2C driver{}; // Create I2C driver.
|
||||
MFRC522 mfrc522{driver}; // Create MFRC522 instance.
|
||||
|
||||
/**
|
||||
* Check firmware only once at startup.
|
||||
*/
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
|
||||
Serial.println(F("*****************************"));
|
||||
Serial.println(F("MFRC522 Digital self test"));
|
||||
Serial.println(F("*****************************"));
|
||||
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show version of PCD - MFRC522 Card Reader.
|
||||
Serial.println(F("-----------------------------"));
|
||||
Serial.println(F("Only known versions supported"));
|
||||
Serial.println(F("-----------------------------"));
|
||||
Serial.println(F("Performing test..."));
|
||||
bool result = mfrc522.PCD_PerformSelfTest(); // Perform the test.
|
||||
Serial.println(F("-----------------------------"));
|
||||
Serial.print(F("Result: "));
|
||||
if (result)
|
||||
Serial.println(F("OK"));
|
||||
else
|
||||
Serial.println(F("DEFECT or UNKNOWN"));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop() {} // nothing to do
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example showing how to read data from a PICC to serial.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
|
||||
* Reader on the Arduino SPI interface.
|
||||
*
|
||||
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
|
||||
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shift+M). When
|
||||
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
|
||||
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
|
||||
* when removing the PICC from reading distance too early.
|
||||
*
|
||||
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
|
||||
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
|
||||
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
|
||||
* keep the PICCs at reading distance until complete.
|
||||
*
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverI2C.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
const uint8_t customAddress = 0x28;
|
||||
|
||||
TwoWire &customI2C = Wire;
|
||||
|
||||
MFRC522DriverI2C driver{customAddress, customI2C}; // Create I2C driver.
|
||||
|
||||
MFRC522 mfrc522{driver}; // Create MFRC522 instance.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show details of PCD - MFRC522 Card Reader details.
|
||||
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if ( !mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example showing how to read data from a PICC to serial.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
|
||||
* Reader on the Arduino SPI interface.
|
||||
*
|
||||
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
|
||||
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shift+M). When
|
||||
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
|
||||
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
|
||||
* when removing the PICC from reading distance too early.
|
||||
*
|
||||
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
|
||||
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
|
||||
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
|
||||
* keep the PICCs at reading distance until complete.
|
||||
*
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_pin(10); // Create pin driver. See typical pin layout above.
|
||||
|
||||
SPIClass &spiClass = SPI; // Alternative SPI e.g. SPI2 or from library e.g. softwarespi.
|
||||
|
||||
const SPISettings spiSettings = SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0); // May have to be set if hardware is not fully compatible to Arduino specifications.
|
||||
|
||||
MFRC522DriverSPI driver{ss_pin, spiClass, spiSettings}; // Create SPI driver.
|
||||
|
||||
MFRC522 mfrc522{driver}; // Create MFRC522 instance.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show details of PCD - MFRC522 Card Reader details.
|
||||
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if ( !mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
|
||||
}
|
||||
70
lib/Arduino_MFRC522v2-master/examples/DumpInfo/DumpInfo.ino
Normal file
70
lib/Arduino_MFRC522v2-master/examples/DumpInfo/DumpInfo.ino
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example showing how to read data from a PICC to serial.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
|
||||
* Reader on the Arduino SPI interface.
|
||||
*
|
||||
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
|
||||
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shift+M). When
|
||||
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
|
||||
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
|
||||
* when removing the PICC from reading distance too early.
|
||||
*
|
||||
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
|
||||
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
|
||||
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
|
||||
* keep the PICCs at reading distance until complete.
|
||||
*
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
//#include <MFRC522DriverI2C.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_pin(10); // Configurable, see typical pin layout above.
|
||||
|
||||
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver.
|
||||
//MFRC522DriverI2C driver{}; // Create I2C driver.
|
||||
MFRC522 mfrc522{driver}; // Create MFRC522 instance.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show details of PCD - MFRC522 Card Reader details.
|
||||
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
|
||||
if ( !mfrc522.PICC_IsNewCardPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Select one of the cards.
|
||||
if ( !mfrc522.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump debug info about the card; PICC_HaltA() is automatically called.
|
||||
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example to change UID of changeable MIFARE card.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* This sample shows how to set the UID on a UID changeable MIFARE card.
|
||||
*
|
||||
* @author Tom Clement
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
//#include <MFRC522DriverI2C.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
#include <MFRC522Hack.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_pin(10); // Configurable, see typical pin layout above.
|
||||
|
||||
MFRC522DriverSPI driver(ss_pin);
|
||||
//MFRC522DriverI2C driver();
|
||||
MFRC522 mfrc522(driver); // Create MFRC522 instance.
|
||||
MFRC522Hack mfrc522Hack(mfrc522, true); // Create MFRC522Hack instance.
|
||||
|
||||
/* Set your new UID here! */
|
||||
constexpr uint8_t newUid[] = {0xDE, 0xAD, 0xBE, 0xEF};
|
||||
|
||||
MFRC522::MIFARE_Key key;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
|
||||
Serial.println(F("This example only works with MIFARE Classic cards."));
|
||||
|
||||
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
|
||||
for (byte i = 0; i < 6; i++) {
|
||||
key.keyByte[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. And if present, select one.
|
||||
if ( !mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial() ) {
|
||||
delay(50);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now a card is selected. The UID and SAK is in mfrc522.uid.
|
||||
|
||||
// Dump UID.
|
||||
Serial.print(F("Card UID:"));
|
||||
MFRC522Debug::PrintSelectedUID(mfrc522, Serial);
|
||||
Serial.println();
|
||||
|
||||
// Set new UID.
|
||||
if ( mfrc522Hack.MIFARE_SetUid(newUid, (byte)4, key, true) ) {
|
||||
Serial.println(F("Wrote new UID to card."));
|
||||
}
|
||||
|
||||
// Halt PICC and re-select it so DumpToSerial doesn't get confused.
|
||||
mfrc522.PICC_HaltA();
|
||||
if ( !mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump the new memory contents.
|
||||
Serial.println(F("New UID and contents:"));
|
||||
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example to fix a broken UID changeable MIFARE cards.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* This sample shows how to fix a broken UID changeable MIFARE cards that have a corrupted sector 0.
|
||||
*
|
||||
* @author Tom Clement
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS SDA(SS) 10 53 D10 10 10
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
//#include <MFRC522DriverI2C.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Hack.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_pin(10); // Configurable, see typical pin layout above.
|
||||
|
||||
MFRC522DriverSPI driver(ss_pin);
|
||||
//MFRC522DriverI2C driver();
|
||||
MFRC522 mfrc522(driver); // Create MFRC522 instance.
|
||||
MFRC522Hack mfrc522Hack(mfrc522, true); // Create MFRC522Hack instance.
|
||||
|
||||
MFRC522::MIFARE_Key key;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
mfrc522.PCD_Init(); // Init MFRC522 board.
|
||||
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
|
||||
Serial.println(F("This example only works with MIFARE Classic cards."));
|
||||
|
||||
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
|
||||
for (byte i = 0; i < 6; i++) {
|
||||
key.keyByte[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if ( mfrc522Hack.MIFARE_UnbrickUidSector() ) {
|
||||
Serial.println(F("Cleared sector 0, set UID to 1234. Card should be responsive again now."));
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* Example showing how to read data from more than one PICC to serial.
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
* This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
*
|
||||
* Example sketch/program showing how to read data from more than one PICC (that is: a RFID Tag or Card) using a
|
||||
* MFRC522 based RFID Reader on the Arduino SPI interface.
|
||||
*
|
||||
* Warning: This may not work! Multiple devices at one SPI are difficult and cause many trouble!! Engineering skill
|
||||
* and knowledge are required!
|
||||
*
|
||||
* @license Released into the public domain.
|
||||
*
|
||||
* Typical pin layout used:
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* MFRC522 Arduino Arduino Arduino Arduino Arduino
|
||||
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
|
||||
* Signal Pin Pin Pin Pin Pin Pin
|
||||
* -----------------------------------------------------------------------------------------
|
||||
* SPI SS 1 SDA(SS) ** custom, take a unused pin, only HIGH/LOW required **
|
||||
* SPI SS 2 SDA(SS) ** custom, take a unused pin, only HIGH/LOW required **
|
||||
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
|
||||
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
|
||||
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
|
||||
*
|
||||
* Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
|
||||
*/
|
||||
|
||||
// Note for i2c:
|
||||
// With i2c possible if every device has a own unique address.
|
||||
// Otherwise a i2c multiplexer is required, which requires a own implementation of MFRC522Driver.h.
|
||||
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
MFRC522DriverPinSimple ss_1_pin(10); // Configurable, take an unused pin, only HIGH/LOW required, must be different to SS 2.
|
||||
MFRC522DriverPinSimple ss_2_pin(8); // Configurable, take an unused pin, only HIGH/LOW required, must be different to SS 1.
|
||||
|
||||
MFRC522DriverSPI driver_1{ss_1_pin};
|
||||
MFRC522DriverSPI driver_2{ss_2_pin};
|
||||
|
||||
MFRC522 readers[]{driver_1, driver_2}; // Create MFRC522 instance.
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
void setup() {
|
||||
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
|
||||
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
|
||||
|
||||
for (MFRC522 reader : readers) {
|
||||
reader.PCD_Init(); // Init each MFRC522 card.
|
||||
Serial.print(F("Reader "));
|
||||
static uint8_t i = 0;
|
||||
i++;
|
||||
Serial.print(i);
|
||||
Serial.print(F(": "));
|
||||
MFRC522Debug::PCD_DumpVersionToSerial(reader, Serial);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop.
|
||||
*/
|
||||
void loop() {
|
||||
// Look for new cards.
|
||||
for (MFRC522 reader : readers) {
|
||||
if (reader.PICC_IsNewCardPresent() && reader.PICC_ReadCardSerial()) {
|
||||
Serial.print(F("Reader "));
|
||||
static uint8_t i = 0;
|
||||
i++;
|
||||
Serial.print(i);
|
||||
|
||||
// Show some details of the PICC (that is: the tag/card).
|
||||
Serial.print(F(": Card UID:"));
|
||||
MFRC522Debug::PrintUID(Serial, reader.uid);
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("PICC type: "));
|
||||
MFRC522::PICC_Type piccType = reader.PICC_GetType(reader.uid.sak);
|
||||
Serial.println(MFRC522Debug::PICC_GetTypeName(piccType));
|
||||
|
||||
// Halt PICC.
|
||||
reader.PICC_HaltA();
|
||||
// Stop encryption on PCD.
|
||||
reader.PCD_StopCrypto1();
|
||||
}
|
||||
}
|
||||
}
|
||||
223
lib/Arduino_MFRC522v2-master/keywords.txt
Normal file
223
lib/Arduino_MFRC522v2-master/keywords.txt
Normal file
@@ -0,0 +1,223 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map for library MFRC522
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# KEYWORD1 Classes, datatypes, and C++ keywords
|
||||
#######################################
|
||||
MFRC522 KEYWORD1
|
||||
MFRC522Extended KEYWORD1
|
||||
PCD_Register KEYWORD1
|
||||
PCD_Command KEYWORD1
|
||||
PCD_RxGain KEYWORD1
|
||||
PICC_Command KEYWORD1
|
||||
MIFARE_Misc KEYWORD1
|
||||
PICC_Type KEYWORD1
|
||||
StatusCode KEYWORD1
|
||||
TagBitRates KEYWORD1
|
||||
Uid KEYWORD1
|
||||
CardInfo KEYWORD1
|
||||
MIFARE_Key KEYWORD1
|
||||
PcbBlock KEYWORD1
|
||||
|
||||
#######################################
|
||||
# KEYWORD2 Methods and functions
|
||||
#######################################
|
||||
|
||||
# Basic interface functions for communicating with the MFRC522
|
||||
PCD_WriteRegister KEYWORD2
|
||||
PCD_WriteRegister KEYWORD2
|
||||
PCD_ReadRegister KEYWORD2
|
||||
PCD_ReadRegister KEYWORD2
|
||||
setBitMask KEYWORD2
|
||||
PCD_SetRegisterBitMask KEYWORD2
|
||||
PCD_ClearRegisterBitMask KEYWORD2
|
||||
PCD_CalculateCRC KEYWORD2
|
||||
|
||||
# Functions for manipulating the MFRC522
|
||||
PCD_Init KEYWORD2
|
||||
PCD_Reset KEYWORD2
|
||||
PCD_AntennaOn KEYWORD2
|
||||
PCD_AntennaOff KEYWORD2
|
||||
PCD_GetAntennaGain KEYWORD2
|
||||
PCD_SetAntennaGain KEYWORD2
|
||||
PCD_PerformSelfTest KEYWORD2
|
||||
|
||||
# Power control functions MFRC522
|
||||
PCD_SoftPowerDown KEYWORD2
|
||||
PCD_SoftPowerUp KEYWORD2
|
||||
|
||||
# Functions for communicating with PICCs
|
||||
PCD_TransceiveData KEYWORD2
|
||||
PCD_CommunicateWithPICC KEYWORD2
|
||||
PICC_RequestA KEYWORD2
|
||||
PICC_WakeupA KEYWORD2
|
||||
PICC_REQA_or_WUPA KEYWORD2
|
||||
PICC_Select KEYWORD2
|
||||
PICC_HaltA KEYWORD2
|
||||
PICC_RATS KEYWORD2
|
||||
PICC_PPS KEYWORD2
|
||||
|
||||
# Functions for communicating with ISO/IEC 14433-4 cards
|
||||
TCL_Transceive KEYWORD2
|
||||
TCL_TransceiveRBlock KEYWORD2
|
||||
TCL_Deselect KEYWORD2
|
||||
|
||||
# Functions for communicating with MIFARE PICCs
|
||||
PCD_Authenticate KEYWORD2
|
||||
PCD_StopCrypto1 KEYWORD2
|
||||
MIFARE_Read KEYWORD2
|
||||
MIFARE_Write KEYWORD2
|
||||
MIFARE_Increment KEYWORD2
|
||||
MIFARE_Ultralight_Write KEYWORD2
|
||||
MIFARE_GetValue KEYWORD2
|
||||
MIFARE_SetValue KEYWORD2
|
||||
PCD_NTAG216_AUTH KEYWORD2
|
||||
|
||||
# Support functions
|
||||
PCD_MIFARE_Transceive KEYWORD2
|
||||
GetStatusCodeName KEYWORD2
|
||||
PICC_GetType KEYWORD2
|
||||
PICC_GetTypeName KEYWORD2
|
||||
|
||||
# Support functions for debugging
|
||||
PCD_DumpVersionToSerial KEYWORD2
|
||||
PICC_DumpToSerial KEYWORD2
|
||||
PICC_DumpDetailsToSerial KEYWORD2
|
||||
PICC_DumpMifareClassicToSerial KEYWORD2
|
||||
PICC_DumpMifareClassicSectorToSerial KEYWORD2
|
||||
PICC_DumpMifareUltralightToSerial KEYWORD2
|
||||
PICC_DumpISO14443_4 KEYWORD2
|
||||
|
||||
# Advanced functions for MIFARE
|
||||
MIFARE_CalculateAccessBits KEYWORD2
|
||||
MIFARE_OpenUidBackdoor KEYWORD2
|
||||
MIFARE_SetUid KEYWORD2
|
||||
MIFARE_UnbrickUidSector KEYWORD2
|
||||
|
||||
# Convenience functions - does not add extra functionality
|
||||
PICC_IsNewCardPresent KEYWORD2
|
||||
PICC_ReadCardSerial KEYWORD2
|
||||
|
||||
#######################################
|
||||
# KEYWORD3 setup and loop functions, as well as the Serial keywords
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# LITERAL1 Constants
|
||||
#######################################
|
||||
CommandReg LITERAL1
|
||||
ComIEnReg LITERAL1
|
||||
DivIEnReg LITERAL1
|
||||
ComIrqReg LITERAL1
|
||||
DivIrqReg LITERAL1
|
||||
ErrorReg LITERAL1
|
||||
Status1Reg LITERAL1
|
||||
Status2Reg LITERAL1
|
||||
FIFODataReg LITERAL1
|
||||
FIFOLevelReg LITERAL1
|
||||
WaterLevelReg LITERAL1
|
||||
ControlReg LITERAL1
|
||||
BitFramingReg LITERAL1
|
||||
CollReg LITERAL1
|
||||
ModeReg LITERAL1
|
||||
TxModeReg LITERAL1
|
||||
RxModeReg LITERAL1
|
||||
TxControlReg LITERAL1
|
||||
TxASKReg LITERAL1
|
||||
TxSelReg LITERAL1
|
||||
RxSelReg LITERAL1
|
||||
RxThresholdReg LITERAL1
|
||||
DemodReg LITERAL1
|
||||
MfTxReg LITERAL1
|
||||
MfRxReg LITERAL1
|
||||
SerialSpeedReg LITERAL1
|
||||
CRCResultRegH LITERAL1
|
||||
CRCResultRegL LITERAL1
|
||||
ModWidthReg LITERAL1
|
||||
RFCfgReg LITERAL1
|
||||
GsNReg LITERAL1
|
||||
CWGsPReg LITERAL1
|
||||
ModGsPReg LITERAL1
|
||||
TModeReg LITERAL1
|
||||
TPrescalerReg LITERAL1
|
||||
TReloadRegH LITERAL1
|
||||
TReloadRegL LITERAL1
|
||||
TCounterValueRegH LITERAL1
|
||||
TCounterValueRegL LITERAL1
|
||||
TestSel1Reg LITERAL1
|
||||
TestSel2Reg LITERAL1
|
||||
TestPinEnReg LITERAL1
|
||||
TestPinValueReg LITERAL1
|
||||
TestBusReg LITERAL1
|
||||
AutoTestReg LITERAL1
|
||||
VersionReg LITERAL1
|
||||
AnalogTestReg LITERAL1
|
||||
TestDAC1Reg LITERAL1
|
||||
TestDAC2Reg LITERAL1
|
||||
TestADCReg LITERAL1
|
||||
PCD_Idle LITERAL1
|
||||
PCD_Mem LITERAL1
|
||||
PCD_GenerateRandomID LITERAL1
|
||||
PCD_CalcCRC LITERAL1
|
||||
PCD_Transmit LITERAL1
|
||||
PCD_NoCmdChange LITERAL1
|
||||
PCD_Receive LITERAL1
|
||||
PCD_Transceive LITERAL1
|
||||
PCD_MFAuthent LITERAL1
|
||||
PCD_SoftReset LITERAL1
|
||||
RxGain_18dB LITERAL1
|
||||
RxGain_23dB LITERAL1
|
||||
RxGain_18dB_2 LITERAL1
|
||||
RxGain_23dB_2 LITERAL1
|
||||
RxGain_33dB LITERAL1
|
||||
RxGain_38dB LITERAL1
|
||||
RxGain_43dB LITERAL1
|
||||
RxGain_48dB LITERAL1
|
||||
RxGain_min LITERAL1
|
||||
RxGain_avg LITERAL1
|
||||
RxGain_max LITERAL1
|
||||
PICC_CMD_REQA LITERAL1
|
||||
PICC_CMD_WUPA LITERAL1
|
||||
PICC_CMD_CT LITERAL1
|
||||
PICC_CMD_SEL_CL1 LITERAL1
|
||||
PICC_CMD_SEL_CL2 LITERAL1
|
||||
PICC_CMD_SEL_CL3 LITERAL1
|
||||
PICC_CMD_HLTA LITERAL1
|
||||
PICC_CMD_RATS LITERAL1
|
||||
PICC_CMD_MF_AUTH_KEY_A LITERAL1
|
||||
PICC_CMD_MF_AUTH_KEY_B LITERAL1
|
||||
PICC_CMD_MF_READ LITERAL1
|
||||
PICC_CMD_MF_WRITE LITERAL1
|
||||
PICC_CMD_MF_DECREMENT LITERAL1
|
||||
PICC_CMD_MF_INCREMENT LITERAL1
|
||||
PICC_CMD_MF_RESTORE LITERAL1
|
||||
PICC_CMD_MF_TRANSFER LITERAL1
|
||||
PICC_CMD_UL_WRITE LITERAL1
|
||||
MF_ACK LITERAL1
|
||||
MF_KEY_SIZE LITERAL1
|
||||
PICC_TYPE_UNKNOWN LITERAL1
|
||||
PICC_TYPE_ISO_14443_4 LITERAL1
|
||||
PICC_TYPE_ISO_18092 LITERAL1
|
||||
PICC_TYPE_MIFARE_MINI LITERAL1
|
||||
PICC_TYPE_MIFARE_1K LITERAL1
|
||||
PICC_TYPE_MIFARE_4K LITERAL1
|
||||
PICC_TYPE_MIFARE_UL LITERAL1
|
||||
PICC_TYPE_MIFARE_PLUS LITERAL1
|
||||
PICC_TYPE_MIFARE_DESFIRE LITERAL1
|
||||
PICC_TYPE_TNP3XXX LITERAL1
|
||||
PICC_TYPE_NOT_COMPLETE LITERAL1
|
||||
STATUS_OK LITERAL1
|
||||
STATUS_ERROR LITERAL1
|
||||
STATUS_COLLISION LITERAL1
|
||||
STATUS_TIMEOUT LITERAL1
|
||||
STATUS_NO_ROOM LITERAL1
|
||||
STATUS_INTERNAL_ERROR LITERAL1
|
||||
STATUS_INVALID LITERAL1
|
||||
STATUS_CRC_WRONG LITERAL1
|
||||
STATUS_MIFARE_NACK LITERAL1
|
||||
FIFO_SIZE LITERAL1
|
||||
BITRATE_106KBITS LITERAL1
|
||||
BITRATE_212KBITS LITERAL1
|
||||
BITRATE_424KBITS LITERAL1
|
||||
BITRATE_848KBITS LITERAL1
|
||||
10
lib/Arduino_MFRC522v2-master/library.properties
Normal file
10
lib/Arduino_MFRC522v2-master/library.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=RFID_MFRC522v2
|
||||
version=2.0.6
|
||||
author=GithubCommunity
|
||||
maintainer=GithubCommunity
|
||||
sentence=Arduino RFID driver library for MFRC522 (SPI, I2C)
|
||||
paragraph=Raw read/write a RFID Card or Tag using the ISO/IEC 14443A/MIFARE interface.
|
||||
category=Communication
|
||||
url=https://github.com/OSSLibraries/Arduino_MFRC522v2
|
||||
architectures=avr,megaavr,STM32F1,teensy,esp8266,esp32,samd
|
||||
depends=
|
||||
42
lib/Arduino_MFRC522v2-master/package.json
Normal file
42
lib/Arduino_MFRC522v2-master/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"remarkConfig": {
|
||||
"plugins": [
|
||||
"remark-preset-lint-recommended",
|
||||
"remark-preset-lint-consistent",
|
||||
"remark-preset-github",
|
||||
[
|
||||
"remark-lint-list-item-indent",
|
||||
"space"
|
||||
],
|
||||
[
|
||||
"remark-lint-emphasis-marker",
|
||||
"*"
|
||||
],
|
||||
[
|
||||
"remark-lint-no-file-name-mixed-case",
|
||||
false
|
||||
],
|
||||
[
|
||||
"remark-lint-maximum-line-length",
|
||||
false
|
||||
],
|
||||
[
|
||||
"remark-contributors",
|
||||
false
|
||||
],
|
||||
[
|
||||
"remark-license",
|
||||
false
|
||||
],
|
||||
[
|
||||
"remark-lint-no-literal-urls",
|
||||
false
|
||||
]
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"remark-preset-github": "^4.0.4",
|
||||
"remark-preset-lint-consistent": "^5.1.2",
|
||||
"remark-preset-lint-recommended": "^6.1.3"
|
||||
}
|
||||
}
|
||||
198
lib/Arduino_MFRC522v2-master/src/MFRC522Constants.h
Normal file
198
lib/Arduino_MFRC522v2-master/src/MFRC522Constants.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
class MFRC522Constants {
|
||||
public:
|
||||
// MFRC522 registers. Described in chapter 9 of the datasheet.
|
||||
enum PCD_Register : byte {
|
||||
// Page 0: Command and status
|
||||
// 0x00 // reserved for future use
|
||||
CommandReg = 0x01, // starts and stops command execution
|
||||
ComIEnReg = 0x02, // enable and disable interrupt request control bits
|
||||
DivIEnReg = 0x03, // enable and disable interrupt request control bits
|
||||
ComIrqReg = 0x04, // interrupt request bits
|
||||
DivIrqReg = 0x05, // interrupt request bits
|
||||
ErrorReg = 0x06, // error bits showing the error status of the last command executed
|
||||
Status1Reg = 0x07, // communication status bits
|
||||
Status2Reg = 0x08, // receiver and transmitter status bits
|
||||
FIFODataReg = 0x09, // input and output of 64 byte FIFO buffer
|
||||
FIFOLevelReg = 0x0A, // number of bytes stored in the FIFO buffer
|
||||
WaterLevelReg = 0x0B, // level for FIFO underflow and overflow warning
|
||||
ControlReg = 0x0C, // miscellaneous control registers
|
||||
BitFramingReg = 0x0D, // adjustments for bit-oriented frames
|
||||
CollReg = 0x0E, // bit position of the first bit-collision detected on the RF interface
|
||||
// 0x0F // reserved for future use
|
||||
|
||||
// Page 1: Command
|
||||
// 0x10 // reserved for future use
|
||||
ModeReg = 0x11, // defines general modes for transmitting and receiving
|
||||
TxModeReg = 0x12, // defines transmission data rate and framing
|
||||
RxModeReg = 0x13, // defines reception data rate and framing
|
||||
TxControlReg = 0x14, // controls the logical behavior of the antenna driver pins TX1 and TX2
|
||||
TxASKReg = 0x15, // controls the setting of the transmission modulation
|
||||
TxSelReg = 0x16, // selects the internal sources for the antenna driver
|
||||
RxSelReg = 0x17, // selects internal receiver settings
|
||||
RxThresholdReg = 0x18, // selects thresholds for the bit decoder
|
||||
DemodReg = 0x19, // defines demodulator settings
|
||||
// 0x1A // reserved for future use
|
||||
// 0x1B // reserved for future use
|
||||
MfTxReg = 0x1C, // controls some MIFARE communication transmit parameters
|
||||
MfRxReg = 0x1D, // controls some MIFARE communication receive parameters
|
||||
// 0x1E // reserved for future use
|
||||
SerialSpeedReg = 0x1F, // selects the speed of the serial UART interface
|
||||
|
||||
// Page 2: Configuration
|
||||
// 0x20 // reserved for future use
|
||||
CRCResultRegH = 0x21, // shows the MSB and LSB values of the CRC calculation
|
||||
CRCResultRegL = 0x22,
|
||||
// 0x23 // reserved for future use
|
||||
ModWidthReg = 0x24, // controls the ModWidth setting?
|
||||
// 0x25 // reserved for future use
|
||||
RFCfgReg = 0x26, // configures the receiver gain
|
||||
GsNReg = 0x27, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
|
||||
CWGsPReg = 0x28, // defines the conductance of the p-driver output during periods of no modulation
|
||||
ModGsPReg = 0x29, // defines the conductance of the p-driver output during periods of modulation
|
||||
TModeReg = 0x2A, // defines settings for the internal timer
|
||||
TPrescalerReg = 0x2B, // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
|
||||
TReloadRegH = 0x2C, // defines the 16-bit timer reload value
|
||||
TReloadRegL = 0x2D,
|
||||
TCounterValueRegH = 0x2E, // shows the 16-bit timer value
|
||||
TCounterValueRegL = 0x2F,
|
||||
|
||||
// Page 3: Test Registers
|
||||
// 0x30 // reserved for future use
|
||||
TestSel1Reg = 0x31, // general test signal configuration
|
||||
TestSel2Reg = 0x32, // general test signal configuration
|
||||
TestPinEnReg = 0x33, // enables pin output driver on pins D1 to D7
|
||||
TestPinValueReg = 0x34, // defines the values for D1 to D7 when it is used as an I/O bus
|
||||
TestBusReg = 0x35, // shows the status of the internal test bus
|
||||
AutoTestReg = 0x36, // controls the digital self-test
|
||||
VersionReg = 0x37, // shows the software version
|
||||
AnalogTestReg = 0x38, // controls the pins AUX1 and AUX2
|
||||
TestDAC1Reg = 0x39, // defines the test value for TestDAC1
|
||||
TestDAC2Reg = 0x3A, // defines the test value for TestDAC2
|
||||
TestADCReg = 0x3B // shows the value of ADC I and Q channels
|
||||
// 0x3C // reserved for production tests
|
||||
// 0x3D // reserved for production tests
|
||||
// 0x3E // reserved for production tests
|
||||
// 0x3F // reserved for production tests
|
||||
};
|
||||
|
||||
// MFRC522 commands. Described in chapter 10 of the datasheet.
|
||||
enum PCD_Command : byte {
|
||||
PCD_Idle = 0x00, // no action, cancels current command execution
|
||||
PCD_Mem = 0x01, // stores 25 bytes into the internal buffer
|
||||
PCD_GenerateRandomID = 0x02, // generates a 10-byte random ID number
|
||||
PCD_CalcCRC = 0x03, // activates the CRC coprocessor or performs a self-test
|
||||
PCD_Transmit = 0x04, // transmits data from the FIFO buffer
|
||||
PCD_NoCmdChange = 0x07, // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
|
||||
PCD_Receive = 0x08, // activates the receiver circuits
|
||||
PCD_Transceive = 0x0C, // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
|
||||
PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
|
||||
PCD_SoftReset = 0x0F // resets the MFRC522
|
||||
};
|
||||
|
||||
// MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD).
|
||||
// Described in 9.3.3.6 / table 98 of the datasheet at https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
|
||||
enum PCD_RxGain : byte {
|
||||
RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
|
||||
RxGain_23dB = 0x01 << 4, // 001b - 23 dB
|
||||
RxGain_18dB_2 = 0x02 << 4, // 010b - 18 dB, it seems 010b is a duplicate for 000b
|
||||
RxGain_23dB_2 = 0x03 << 4, // 011b - 23 dB, it seems 011b is a duplicate for 001b
|
||||
RxGain_33dB = 0x04 << 4, // 100b - 33 dB, average, and typical default
|
||||
RxGain_38dB = 0x05 << 4, // 101b - 38 dB
|
||||
RxGain_43dB = 0x06 << 4, // 110b - 43 dB
|
||||
RxGain_48dB = 0x07 << 4, // 111b - 48 dB, maximum
|
||||
RxGain_min = 0x00 << 4, // 000b - 18 dB, minimum, convenience for RxGain_18dB
|
||||
RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB
|
||||
RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB
|
||||
};
|
||||
|
||||
// Version of chip / firmware.
|
||||
enum PCD_Version : byte {
|
||||
Version_Counterfeit = 0x12,
|
||||
Version_FM17522 = 0x88,
|
||||
Version_FM17522_1 = 0xb2,
|
||||
Version_FM17522E = 0x89,
|
||||
Version_0_0 = 0x90,
|
||||
Version_1_0 = 0x91,
|
||||
Version_2_0 = 0x92,
|
||||
Version_Unknown = 0xff,
|
||||
};
|
||||
|
||||
// Commands sent to the PICC.
|
||||
enum PICC_Command : byte {
|
||||
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
|
||||
PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
|
||||
PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
|
||||
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
|
||||
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
|
||||
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
|
||||
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
|
||||
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
|
||||
PICC_CMD_RATS = 0xE0, // Request command for Answer To Reset.
|
||||
// The commands used for MIFARE Classic (from http://www.mouser.com/ds/2/302/MF1S503x-89574.pdf, Section 9)
|
||||
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
|
||||
// The read/write commands can also be used for MIFARE Ultralight.
|
||||
PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
|
||||
PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
|
||||
PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
|
||||
PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
|
||||
PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
|
||||
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
|
||||
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
|
||||
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
|
||||
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
|
||||
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
|
||||
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
|
||||
};
|
||||
|
||||
// MIFARE constants that does not fit anywhere else
|
||||
enum MIFARE_Misc {
|
||||
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
|
||||
MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
|
||||
};
|
||||
|
||||
// PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
|
||||
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
|
||||
enum PICC_Type : byte {
|
||||
PICC_TYPE_UNKNOWN,
|
||||
PICC_TYPE_ISO_14443_4, // PICC compliant with ISO/IEC 14443-4.
|
||||
PICC_TYPE_ISO_18092, // PICC compliant with ISO/IEC 18092 (NFC).
|
||||
PICC_TYPE_MIFARE_MINI, // MIFARE Classic protocol, 320 bytes.
|
||||
PICC_TYPE_MIFARE_1K, // MIFARE Classic protocol, 1KB.
|
||||
PICC_TYPE_MIFARE_4K, // MIFARE Classic protocol, 4KB.
|
||||
PICC_TYPE_MIFARE_UL, // MIFARE Ultralight or Ultralight C.
|
||||
PICC_TYPE_MIFARE_PLUS, // MIFARE Plus.
|
||||
PICC_TYPE_MIFARE_DESFIRE, // MIFARE DESFire.
|
||||
PICC_TYPE_TNP3XXX, // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure.
|
||||
PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates UID is not complete.
|
||||
};
|
||||
|
||||
// Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
|
||||
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
|
||||
enum StatusCode : byte {
|
||||
STATUS_OK, // Success.
|
||||
STATUS_ERROR, // Error in communication.
|
||||
STATUS_COLLISION, // Collision detected.
|
||||
STATUS_TIMEOUT, // Timeout in communication.
|
||||
STATUS_NO_ROOM, // A buffer is not big enough.
|
||||
STATUS_INTERNAL_ERROR, // Internal error in the code. Should not happen ;-)
|
||||
STATUS_INVALID, // Invalid argument.
|
||||
STATUS_CRC_WRONG, // The CRC_A does not match.
|
||||
STATUS_UNKNOWN,
|
||||
STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK.
|
||||
};
|
||||
|
||||
// A struct used for passing the UID of a PICC.
|
||||
typedef struct {
|
||||
byte size; // Number of bytes in the UID. 4, 7 or 10.
|
||||
byte uidByte[10];
|
||||
byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
|
||||
} Uid;
|
||||
|
||||
// A struct used for passing a MIFARE Crypto1 key.
|
||||
typedef struct {
|
||||
byte keyByte[MIFARE_Misc::MF_KEY_SIZE];
|
||||
} MIFARE_Key;
|
||||
};
|
||||
434
lib/Arduino_MFRC522v2-master/src/MFRC522Debug.cpp
Normal file
434
lib/Arduino_MFRC522v2-master/src/MFRC522Debug.cpp
Normal file
@@ -0,0 +1,434 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#include "MFRC522Debug.h"
|
||||
|
||||
/**
|
||||
* Returns a __FlashStringHelper pointer to the PICC type name.
|
||||
*
|
||||
* @return const __FlashStringHelper *
|
||||
*/
|
||||
const __FlashStringHelper *MFRC522Debug::PICC_GetTypeName(PICC_Type piccType ///< One of the PICC_Type enums.
|
||||
) {
|
||||
switch(piccType) {
|
||||
case PICC_Type::PICC_TYPE_ISO_14443_4:
|
||||
return F("PICC compliant with ISO/IEC 14443-4");
|
||||
case PICC_Type::PICC_TYPE_ISO_18092:
|
||||
return F("PICC compliant with ISO/IEC 18092 (NFC)");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_MINI:
|
||||
return F("MIFARE Mini, 320 bytes");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_1K:
|
||||
return F("MIFARE 1KB");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_4K:
|
||||
return F("MIFARE 4KB");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_UL:
|
||||
return F("MIFARE Ultralight or Ultralight C");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_PLUS:
|
||||
return F("MIFARE Plus");
|
||||
case PICC_Type::PICC_TYPE_MIFARE_DESFIRE:
|
||||
return F("MIFARE DESFire");
|
||||
case PICC_Type::PICC_TYPE_TNP3XXX:
|
||||
return F("MIFARE TNP3XXX");
|
||||
case PICC_Type::PICC_TYPE_NOT_COMPLETE:
|
||||
return F("SAK indicates UID is not complete.");
|
||||
case PICC_Type::PICC_TYPE_UNKNOWN:
|
||||
default:
|
||||
return F("Unknown type");
|
||||
}
|
||||
} // End PICC_GetTypeName()
|
||||
|
||||
/**
|
||||
* Returns a __FlashStringHelper pointer to a status code name.
|
||||
*
|
||||
* @return const __FlashStringHelper *
|
||||
*/
|
||||
const __FlashStringHelper *MFRC522Debug::GetStatusCodeName(StatusCode code ///< One of the StatusCode enums.
|
||||
) {
|
||||
switch(code) {
|
||||
case StatusCode::STATUS_OK:
|
||||
return F("Success.");
|
||||
case StatusCode::STATUS_ERROR:
|
||||
return F("Error in communication.");
|
||||
case StatusCode::STATUS_COLLISION:
|
||||
return F("collision detected.");
|
||||
case StatusCode::STATUS_TIMEOUT:
|
||||
return F("Timeout in communication.");
|
||||
case StatusCode::STATUS_NO_ROOM:
|
||||
return F("A buffer is not big enough.");
|
||||
case StatusCode::STATUS_INTERNAL_ERROR:
|
||||
return F("Internal error in the code. Should not happen.");
|
||||
case StatusCode::STATUS_INVALID:
|
||||
return F("Invalid argument.");
|
||||
case StatusCode::STATUS_CRC_WRONG:
|
||||
return F("The CRC_A does not match.");
|
||||
case StatusCode::STATUS_MIFARE_NACK:
|
||||
return F("A MIFARE PICC responded with NAK.");
|
||||
default:
|
||||
return F("Unknown error");
|
||||
}
|
||||
} // End GetStatusCodeName()
|
||||
|
||||
void MFRC522Debug::PrintUID(Print &logPrint, const MFRC522Constants::Uid &uid) {
|
||||
for(byte i = 0; i < uid.size; i++) {
|
||||
logPrint.print(uid.uidByte[i] < 0x10 ? " 0" : " ");
|
||||
logPrint.print(uid.uidByte[i], HEX);
|
||||
}
|
||||
}
|
||||
|
||||
void MFRC522Debug::PrintSelectedUID(MFRC522 &device, Print &logPrint) {
|
||||
PrintUID(logPrint, device.uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps debug info about the connected PCD to Serial.
|
||||
* Shows all known firmware versions.
|
||||
*/
|
||||
void MFRC522Debug::PCD_DumpVersionToSerial(MFRC522 &device, Print &logPrint) {
|
||||
// Get the MFRC522 firmware version.
|
||||
PCD_Version version = device.PCD_GetVersion();
|
||||
|
||||
if(version != PCD_Version::Version_Unknown) {
|
||||
logPrint.print(F("Firmware Version: 0x"));
|
||||
logPrint.print(version, HEX);
|
||||
}
|
||||
// Human readable version.
|
||||
switch(version) {
|
||||
case 0xb2:
|
||||
logPrint.println(F(" = FM17522_1"));
|
||||
break;
|
||||
case 0x88:
|
||||
logPrint.println(F(" = FM17522"));
|
||||
break;
|
||||
case 0x89:
|
||||
logPrint.println(F(" = FM17522E"));
|
||||
break;
|
||||
case 0x90:
|
||||
logPrint.println(F(" = v0.0"));
|
||||
break;
|
||||
case 0x91:
|
||||
logPrint.println(F(" = v1.0"));
|
||||
break;
|
||||
case 0x92:
|
||||
logPrint.println(F(" = v2.0"));
|
||||
break;
|
||||
case 0x12:
|
||||
logPrint.println(F(" = counterfeit chip"));
|
||||
break;
|
||||
default:
|
||||
logPrint.println(F(" = (unknown)"));
|
||||
}
|
||||
// When 0x00 or 0xFF is returned, communication probably failed
|
||||
if(version == PCD_Version::Version_Unknown) {
|
||||
logPrint.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
|
||||
}
|
||||
} // End PCD_DumpVersionToSerial()
|
||||
|
||||
/**
|
||||
* Dumps debug info about the selected PICC to Serial.
|
||||
* On success the PICC is halted after dumping the data.
|
||||
* For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried.
|
||||
*/
|
||||
void MFRC522Debug::PICC_DumpToSerial(MFRC522 &device, Print &logPrint,
|
||||
Uid *uid ///< Pointer to Uid struct returned from a successful PICC_Select().
|
||||
) {
|
||||
MIFARE_Key key;
|
||||
|
||||
// Dump UID, SAK and Type
|
||||
PICC_DumpDetailsToSerial(device, logPrint, uid);
|
||||
|
||||
// Dump contents
|
||||
PICC_Type piccType = device.PICC_GetType(uid->sak);
|
||||
switch(piccType) {
|
||||
case PICC_Type::PICC_TYPE_MIFARE_MINI:
|
||||
case PICC_Type::PICC_TYPE_MIFARE_1K:
|
||||
case PICC_Type::PICC_TYPE_MIFARE_4K:
|
||||
// All keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
|
||||
for(byte i = 0; i < 6; i++) {
|
||||
key.keyByte[i] = 0xFF;
|
||||
}
|
||||
PICC_DumpMifareClassicToSerial(device, logPrint, uid, piccType, &key);
|
||||
break;
|
||||
|
||||
case PICC_Type::PICC_TYPE_MIFARE_UL:
|
||||
PICC_DumpMifareUltralightToSerial(device, logPrint);
|
||||
break;
|
||||
|
||||
case PICC_Type::PICC_TYPE_ISO_14443_4:
|
||||
case PICC_Type::PICC_TYPE_MIFARE_DESFIRE:
|
||||
case PICC_Type::PICC_TYPE_ISO_18092:
|
||||
case PICC_Type::PICC_TYPE_MIFARE_PLUS:
|
||||
case PICC_Type::PICC_TYPE_TNP3XXX:
|
||||
logPrint.println(F("Dumping memory contents not implemented for that PICC type."));
|
||||
break;
|
||||
|
||||
case PICC_Type::PICC_TYPE_UNKNOWN:
|
||||
case PICC_Type::PICC_TYPE_NOT_COMPLETE:
|
||||
default:
|
||||
break; // No memory dump here
|
||||
}
|
||||
|
||||
logPrint.println();
|
||||
device.PICC_HaltA(); // Already done if it was a MIFARE Classic PICC.
|
||||
} // End PICC_DumpToSerial()
|
||||
|
||||
/**
|
||||
* Dumps card info (UID,SAK,Type) about the selected PICC to Serial.
|
||||
*/
|
||||
void MFRC522Debug::PICC_DumpDetailsToSerial(MFRC522 &device, Print &logPrint,
|
||||
Uid *uid ///< Pointer to Uid struct returned from a successful PICC_Select().
|
||||
) {
|
||||
// UID
|
||||
logPrint.print(F("Card UID:"));
|
||||
for(byte i = 0; i < uid->size; i++) {
|
||||
if(uid->uidByte[i] < 0x10)
|
||||
logPrint.print(F(" 0"));
|
||||
else
|
||||
logPrint.print(F(" "));
|
||||
logPrint.print(uid->uidByte[i], HEX);
|
||||
}
|
||||
logPrint.println();
|
||||
|
||||
// SAK
|
||||
logPrint.print(F("Card SAK: "));
|
||||
if(uid->sak < 0x10)
|
||||
logPrint.print(F("0"));
|
||||
logPrint.println(uid->sak, HEX);
|
||||
|
||||
// (suggested) PICC type
|
||||
PICC_Type piccType = device.PICC_GetType(uid->sak);
|
||||
logPrint.print(F("PICC type: "));
|
||||
logPrint.println(PICC_GetTypeName(piccType));
|
||||
} // End PICC_DumpDetailsToSerial()
|
||||
|
||||
/**
|
||||
* Dumps memory contents of a MIFARE Classic PICC.
|
||||
* On success the PICC is halted after dumping the data.
|
||||
*/
|
||||
void MFRC522Debug::PICC_DumpMifareClassicToSerial(MFRC522 &device, Print &logPrint,
|
||||
Uid *uid, ///< Pointer to Uid struct returned from a successful PICC_Select().
|
||||
PICC_Type piccType, ///< One of the PICC_Type enums.
|
||||
MIFARE_Key *key ///< Key A used for all sectors.
|
||||
) {
|
||||
byte no_of_sectors = 0;
|
||||
switch(piccType) {
|
||||
case PICC_Type::PICC_TYPE_MIFARE_MINI:
|
||||
// Has 5 sectors * 4 blocks/sector * 16 bytes/block = 320 bytes.
|
||||
no_of_sectors = 5;
|
||||
break;
|
||||
|
||||
case PICC_Type::PICC_TYPE_MIFARE_1K:
|
||||
// Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes.
|
||||
no_of_sectors = 16;
|
||||
break;
|
||||
|
||||
case PICC_Type::PICC_TYPE_MIFARE_4K:
|
||||
// Has (32 sectors * 4 blocks/sector + 8 sectors * 16 blocks/sector) * 16 bytes/block = 4096 bytes.
|
||||
no_of_sectors = 40;
|
||||
break;
|
||||
|
||||
default: // Should not happen. Ignore.
|
||||
break;
|
||||
}
|
||||
|
||||
// Dump sectors, highest address first.
|
||||
if(no_of_sectors) {
|
||||
logPrint.println(F("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits"));
|
||||
for(int8_t i = no_of_sectors-1; i >= 0; i--) {
|
||||
PICC_DumpMifareClassicSectorToSerial(device, logPrint, uid, key, i);
|
||||
}
|
||||
}
|
||||
device.PICC_HaltA(); // Halt the PICC before stopping the encrypted session.
|
||||
device.PCD_StopCrypto1();
|
||||
} // End PICC_DumpMifareClassicToSerial()
|
||||
|
||||
|
||||
/**
|
||||
* Dumps memory contents of a sector of a MIFARE Classic PICC.
|
||||
* Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1.
|
||||
* Always uses PICC_Command::PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits.
|
||||
*/
|
||||
void MFRC522Debug::PICC_DumpMifareClassicSectorToSerial(MFRC522 &device, Print &logPrint,
|
||||
Uid *uid, ///< Pointer to Uid struct returned from a successful PICC_Select().
|
||||
MIFARE_Key *key, ///< Key A for the sector.
|
||||
byte sector ///< The sector to dump, 0..39.
|
||||
) {
|
||||
MFRC522::StatusCode status;
|
||||
byte firstBlock; // Address of lowest address to dump actually last block dumped)
|
||||
byte no_of_blocks; // Number of blocks in sector
|
||||
bool isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector.
|
||||
|
||||
// The access bits are stored in a peculiar fashion.
|
||||
// There are four groups:
|
||||
// g[3] Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)
|
||||
// g[2] Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)
|
||||
// g[1] Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)
|
||||
// g[0] Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)
|
||||
// Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB.
|
||||
// The four CX bits are stored together in a nible cx and an inverted nible cx_.
|
||||
byte c1, c2, c3; // Nibbles
|
||||
byte c1_, c2_, c3_; // Inverted nibbles
|
||||
bool invertedError; // True if one of the inverted nibbles did not match
|
||||
byte g[4]; // Access bits for each of the four groups.
|
||||
byte group; // 0-3 - active group for access bits
|
||||
bool firstInGroup; // True for the first block dumped in the group
|
||||
|
||||
// Determine position and size of sector.
|
||||
if(sector < 32) { // Sectors 0..31 has 4 blocks each
|
||||
no_of_blocks = 4;
|
||||
firstBlock = sector*no_of_blocks;
|
||||
} else if(sector < 40) { // Sectors 32-39 has 16 blocks each
|
||||
no_of_blocks = 16;
|
||||
firstBlock = 128+(sector-32)*no_of_blocks;
|
||||
} else { // Illegal input, no MIFARE Classic PICC has more than 40 sectors.
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump blocks, highest address first.
|
||||
byte byteCount;
|
||||
byte buffer[18];
|
||||
byte blockAddr;
|
||||
isSectorTrailer = true;
|
||||
invertedError = false; // Avoid "unused variable" warning.
|
||||
for(int8_t blockOffset = no_of_blocks-1; blockOffset >= 0; blockOffset--) {
|
||||
blockAddr = firstBlock+blockOffset;
|
||||
// Sector number - only on first line
|
||||
if(isSectorTrailer) {
|
||||
if(sector < 10)
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
else
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
logPrint.print(sector);
|
||||
logPrint.print(F(" "));
|
||||
} else {
|
||||
logPrint.print(F(" "));
|
||||
}
|
||||
// Block number
|
||||
if(blockAddr < 10)
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
else {
|
||||
if(blockAddr < 100)
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
else
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
}
|
||||
logPrint.print(blockAddr);
|
||||
logPrint.print(F(" "));
|
||||
// Establish encrypted communications before reading the first block
|
||||
if(isSectorTrailer) {
|
||||
status = device.PCD_Authenticate(PICC_Command::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid);
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
logPrint.print(F("PCD_Authenticate() failed: "));
|
||||
logPrint.println(GetStatusCodeName(status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Read block
|
||||
byteCount = sizeof(buffer);
|
||||
status = device.MIFARE_Read(blockAddr, buffer, &byteCount);
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
logPrint.print(F("MIFARE_Read() failed: "));
|
||||
logPrint.println(GetStatusCodeName(status));
|
||||
continue;
|
||||
}
|
||||
// Dump data
|
||||
for(byte index = 0; index < 16; index++) {
|
||||
if(buffer[index] < 0x10)
|
||||
logPrint.print(F(" 0"));
|
||||
else
|
||||
logPrint.print(F(" "));
|
||||
logPrint.print(buffer[index], HEX);
|
||||
if((index%4) == 3) {
|
||||
logPrint.print(F(" "));
|
||||
}
|
||||
}
|
||||
// Parse sector trailer data
|
||||
if(isSectorTrailer) {
|
||||
c1 = buffer[7] >> 4;
|
||||
c2 = buffer[8] & 0xF;
|
||||
c3 = buffer[8] >> 4;
|
||||
c1_ = buffer[6] & 0xF;
|
||||
c2_ = buffer[6] >> 4;
|
||||
c3_ = buffer[7] & 0xF;
|
||||
invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF));
|
||||
g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0);
|
||||
g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1);
|
||||
g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2);
|
||||
g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3);
|
||||
isSectorTrailer = false;
|
||||
}
|
||||
|
||||
// Which access group is this block in?
|
||||
if(no_of_blocks == 4) {
|
||||
group = blockOffset;
|
||||
firstInGroup = true;
|
||||
} else {
|
||||
group = blockOffset/5;
|
||||
firstInGroup = (group == 3) || (group != (blockOffset+1)/5);
|
||||
}
|
||||
|
||||
if(firstInGroup) {
|
||||
// Print access bits
|
||||
logPrint.print(F(" [ "));
|
||||
logPrint.print((g[group] >> 2) & 1, DEC);
|
||||
logPrint.print(F(" "));
|
||||
logPrint.print((g[group] >> 1) & 1, DEC);
|
||||
logPrint.print(F(" "));
|
||||
logPrint.print((g[group] >> 0) & 1, DEC);
|
||||
logPrint.print(F(" ] "));
|
||||
if(invertedError) {
|
||||
logPrint.print(F(" Inverted access bits did not match! "));
|
||||
}
|
||||
}
|
||||
|
||||
if(group != 3 && (g[group] == 1 || g[group] == 6)) { // Not a sector trailer, a value block
|
||||
int32_t value = (int32_t(buffer[3]) << 24) | (int32_t(buffer[2]) << 16) | (int32_t(buffer[1]) << 8) | int32_t(buffer[0]);
|
||||
logPrint.print(F(" Value=0x"));
|
||||
logPrint.print(value, HEX);
|
||||
logPrint.print(F(" Adr=0x"));
|
||||
logPrint.print(buffer[12], HEX);
|
||||
}
|
||||
logPrint.println();
|
||||
}
|
||||
|
||||
return;
|
||||
} // End PICC_DumpMifareClassicSectorToSerial()
|
||||
|
||||
/**
|
||||
* Dumps memory contents of a MIFARE Ultralight PICC.
|
||||
*/
|
||||
void MFRC522Debug::PICC_DumpMifareUltralightToSerial(MFRC522 &device, Print &logPrint) {
|
||||
StatusCode status;
|
||||
byte byteCount;
|
||||
byte buffer[18];
|
||||
byte i;
|
||||
|
||||
logPrint.println(F("Page 0 1 2 3"));
|
||||
// Try the mpages of the original Ultralight. Ultralight C has more pages.
|
||||
for(byte page = 0; page < 16; page += 4) { // Read returns data for 4 pages at a time.
|
||||
// Read pages
|
||||
byteCount = sizeof(buffer);
|
||||
status = device.MIFARE_Read(page, buffer, &byteCount);
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
logPrint.print(F("MIFARE_Read() failed: "));
|
||||
logPrint.println(GetStatusCodeName(status));
|
||||
break;
|
||||
}
|
||||
// Dump data
|
||||
for(byte offset = 0; offset < 4; offset++) {
|
||||
i = page+offset;
|
||||
if(i < 10)
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
else
|
||||
logPrint.print(F(" ")); // Pad with spaces
|
||||
logPrint.print(i);
|
||||
logPrint.print(F(" "));
|
||||
for(byte index = 0; index < 4; index++) {
|
||||
i = 4*offset+index;
|
||||
if(buffer[i] < 0x10)
|
||||
logPrint.print(F(" 0"));
|
||||
else
|
||||
logPrint.print(F(" "));
|
||||
logPrint.print(buffer[i], HEX);
|
||||
}
|
||||
logPrint.println();
|
||||
}
|
||||
}
|
||||
} // End PICC_DumpMifareUltralightToSerial()
|
||||
33
lib/Arduino_MFRC522v2-master/src/MFRC522Debug.h
Normal file
33
lib/Arduino_MFRC522v2-master/src/MFRC522Debug.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522Constants.h>
|
||||
#include <MFRC522v2.h>
|
||||
|
||||
class MFRC522Debug {
|
||||
private:
|
||||
using StatusCode = MFRC522Constants::StatusCode;
|
||||
using PICC_Type = MFRC522Constants::PICC_Type;
|
||||
using PICC_Command = MFRC522Constants::PICC_Command;
|
||||
using PCD_Version = MFRC522Constants::PCD_Version;
|
||||
using Uid = MFRC522Constants::Uid;
|
||||
using MIFARE_Key = MFRC522Constants::MIFARE_Key;
|
||||
|
||||
public:
|
||||
// Get human readable code and type
|
||||
static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type);
|
||||
static const __FlashStringHelper *GetStatusCodeName(StatusCode code);
|
||||
|
||||
// Support functions for debugging
|
||||
// Injected Arduino API with Print* could be replaced by void* if required.
|
||||
static void PrintUID(Print &logPrint, const Uid &uid);
|
||||
static void PrintSelectedUID(MFRC522 &device, Print &logPrint);
|
||||
static void PCD_DumpVersionToSerial(MFRC522 &device, Print &logPrint);
|
||||
|
||||
static void PICC_DumpToSerial(MFRC522 &device, Print &logPrint, Uid *uid);
|
||||
static void PICC_DumpDetailsToSerial(MFRC522 &device, Print &logPrint, Uid *uid);
|
||||
static void PICC_DumpMifareClassicToSerial(MFRC522 &device, Print &logPrint, Uid *uid, PICC_Type piccType, MIFARE_Key *key);
|
||||
static void PICC_DumpMifareClassicSectorToSerial(MFRC522 &device, Print &logPrint, Uid *uid, MIFARE_Key *key, byte sector);
|
||||
static void PICC_DumpMifareUltralightToSerial(MFRC522 &device, Print &logPrint);
|
||||
};
|
||||
31
lib/Arduino_MFRC522v2-master/src/MFRC522Driver.h
Normal file
31
lib/Arduino_MFRC522v2-master/src/MFRC522Driver.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522Constants.h>
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class MFRC522Driver {
|
||||
public:
|
||||
//typedef MFRC522Constants::PCD_Register PCD_Register;
|
||||
using PCD_Register = MFRC522Constants::PCD_Register;
|
||||
|
||||
// Default value for unused pin
|
||||
static constexpr uint8_t UNUSED_PIN = UINT8_MAX;
|
||||
|
||||
virtual bool init() = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void PCD_WriteRegister(const PCD_Register reg, const byte value) = 0;
|
||||
virtual void PCD_WriteRegister(const PCD_Register reg, const byte count, byte *const values) = 0;
|
||||
virtual byte PCD_ReadRegister(const PCD_Register reg) = 0;
|
||||
virtual void PCD_ReadRegister(const PCD_Register reg, const byte count, byte *const values, const byte rxAlign = 0) = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
MFRC522Driver() = default;
|
||||
};
|
||||
105
lib/Arduino_MFRC522v2-master/src/MFRC522DriverI2C.cpp
Normal file
105
lib/Arduino_MFRC522v2-master/src/MFRC522DriverI2C.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#include "MFRC522DriverI2C.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522DriverI2C
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool MFRC522DriverI2C::init() {
|
||||
// TODO avoid double init.
|
||||
_wire.begin(); // Returns type void, no check possible.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte to the specified register in the MFRC522 chip.
|
||||
* The interface is described in the datasheet section 8.1.4.
|
||||
*/
|
||||
void MFRC522DriverI2C::PCD_WriteRegister(const PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
|
||||
const byte value ///< The value to write.
|
||||
) {
|
||||
_wire.beginTransmission(_slaveAdr);
|
||||
_wire.write(reg);
|
||||
_wire.write(value);
|
||||
_wire.endTransmission();
|
||||
} // End PCD_WriteRegister().
|
||||
|
||||
/**
|
||||
* Writes a number of bytes to the specified register in the MFRC522 chip.
|
||||
* The interface is described in the datasheet section 8.1.4.
|
||||
*/
|
||||
void MFRC522DriverI2C::PCD_WriteRegister(const MFRC522Constants::PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
|
||||
const byte count, ///< The number of bytes to write to the register.
|
||||
byte *const values ///< The values to write. Byte array.
|
||||
) {
|
||||
_wire.beginTransmission(_slaveAdr);
|
||||
_wire.write(reg);
|
||||
_wire.write(values, count);
|
||||
_wire.endTransmission();
|
||||
} // End PCD_WriteRegister()
|
||||
|
||||
/**
|
||||
* Reads a byte from the specified register in the MFRC522 chip.
|
||||
* The interface is described in the datasheet section 8.1.4.
|
||||
*/
|
||||
byte MFRC522DriverI2C::PCD_ReadRegister(const PCD_Register reg ///< The register to read from. One of the PCD_Register enums.
|
||||
) {
|
||||
byte value;
|
||||
|
||||
_wire.beginTransmission(_slaveAdr);
|
||||
_wire.write(reg);
|
||||
_wire.endTransmission();
|
||||
|
||||
_wire.requestFrom(_slaveAdr, (uint8_t)1);
|
||||
//while(!_wire.available()); // Dangerous! Might block! Wait for byte to be available. TODO timeout detection.
|
||||
value = (uint8_t)_wire.read();
|
||||
_wire.endTransmission();
|
||||
|
||||
return value;
|
||||
} // End PCD_ReadRegister()
|
||||
|
||||
/**
|
||||
* Reads a number of bytes from the specified register in the MFRC522 chip.
|
||||
* The interface is described in the datasheet section 8.1.2.
|
||||
*/
|
||||
void MFRC522DriverI2C::PCD_ReadRegister(const PCD_Register reg, ///< The register to read from. One of the PCD_Register enums.
|
||||
const byte count, ///< The number of bytes to read.
|
||||
byte *const values, ///< Byte array to store the values in.
|
||||
const byte rxAlign ///< Only bit positions rxAlign..7 in values[0] are updated.
|
||||
) {
|
||||
// Sanity check.
|
||||
if(count == 0 || values == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte index = 0;
|
||||
|
||||
_wire.beginTransmission(_slaveAdr);
|
||||
_wire.write(reg); // Tell MFRC522 which register address we want to read.
|
||||
_wire.endTransmission();
|
||||
|
||||
_wire.requestFrom(_slaveAdr, count);
|
||||
|
||||
// Todo: is waiting for byte to be available required?
|
||||
// With thanks to arozcan (https://github.com/arozcan/MFRC522-I2C-Library), but slightly modified:
|
||||
while(_wire.available() && index < count) {
|
||||
if(index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0]
|
||||
// Create bit mask for bit positions rxAlign..7
|
||||
byte mask = 0;
|
||||
|
||||
for(byte i = rxAlign; i <= 7; i++) {
|
||||
mask |= (1 << i);
|
||||
}
|
||||
// Read value and tell that we want to read the same address again.
|
||||
byte value = (byte)_wire.read(); // returns int but only with uint8 content
|
||||
|
||||
// Apply mask to both current value of values[0] and the new data in value.
|
||||
values[0] = (values[index] & ~mask) | (value & mask);
|
||||
} else { // Normal case
|
||||
values[index] = (byte)_wire.read(); // returns int but only with uint8 content
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
// Fixme: flush wire if still data available?
|
||||
} // End PCD_ReadRegister()
|
||||
38
lib/Arduino_MFRC522v2-master/src/MFRC522DriverI2C.h
Normal file
38
lib/Arduino_MFRC522v2-master/src/MFRC522DriverI2C.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <Wire.h>
|
||||
#include <MFRC522Driver.h>
|
||||
|
||||
class MFRC522DriverI2C : public MFRC522Driver {
|
||||
public:
|
||||
//using PCD_Register = MFRC522Constants::PCD_Register;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for setting up the Arduino.
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool init() override;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522.
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_WriteRegister(const PCD_Register reg, const byte value) override;
|
||||
void PCD_WriteRegister(const PCD_Register reg, const byte count, byte *const values) override;
|
||||
byte PCD_ReadRegister(const PCD_Register reg) override;
|
||||
void PCD_ReadRegister(const PCD_Register reg, const byte count, byte *const values, const byte rxAlign = 0) override;
|
||||
|
||||
|
||||
MFRC522DriverI2C(
|
||||
const byte slaveAdr = 0x28,
|
||||
TwoWire &wire = Wire
|
||||
) : MFRC522Driver(),
|
||||
_slaveAdr(slaveAdr),
|
||||
_wire(wire) {};
|
||||
|
||||
protected:
|
||||
// Address of mfrc522.
|
||||
const byte _slaveAdr;
|
||||
|
||||
// Wire instance.
|
||||
TwoWire &_wire;
|
||||
};
|
||||
14
lib/Arduino_MFRC522v2-master/src/MFRC522DriverPin.h
Normal file
14
lib/Arduino_MFRC522v2-master/src/MFRC522DriverPin.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Must be pure virtual.
|
||||
*/
|
||||
class MFRC522DriverPin {
|
||||
public:
|
||||
virtual bool init() = 0;
|
||||
|
||||
virtual void high() = 0;
|
||||
|
||||
virtual void low() = 0;
|
||||
};
|
||||
26
lib/Arduino_MFRC522v2-master/src/MFRC522DriverPinSimple.h
Normal file
26
lib/Arduino_MFRC522v2-master/src/MFRC522DriverPinSimple.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522DriverPin.h>
|
||||
|
||||
|
||||
class MFRC522DriverPinSimple : public MFRC522DriverPin {
|
||||
public:
|
||||
MFRC522DriverPinSimple(const uint8_t pin) : _pin{pin} {};
|
||||
|
||||
bool init() override {
|
||||
pinMode(_pin, OUTPUT);
|
||||
return true;
|
||||
};
|
||||
|
||||
void high() override {
|
||||
digitalWrite(_pin, HIGH);
|
||||
};
|
||||
|
||||
void low() override {
|
||||
digitalWrite(_pin, LOW);
|
||||
};
|
||||
protected:
|
||||
const uint8_t _pin;
|
||||
};
|
||||
108
lib/Arduino_MFRC522v2-master/src/MFRC522DriverSPI.cpp
Normal file
108
lib/Arduino_MFRC522v2-master/src/MFRC522DriverSPI.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#include "MFRC522DriverSPI.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522DriverSPI
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool MFRC522DriverSPI::init() {
|
||||
// Initialise SPI, Arduino implementation is protected against double initialisation.
|
||||
_spiClass.begin(); // Returns type void, no check possible.
|
||||
|
||||
// Set the chipSelectPin as digital output, do not select the slave yet.
|
||||
if(_chipSelectPin.init() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_chipSelectPin.high();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte to the specified register in the MFRC522DriverSPI chip.
|
||||
* The interface is described in the datasheet section 8.1.2.
|
||||
*/
|
||||
void MFRC522DriverSPI::PCD_WriteRegister(const PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
|
||||
const byte value ///< The value to write.
|
||||
) {
|
||||
_spiClass.beginTransaction(_spiSettings); // Set the settings to work with SPI bus
|
||||
_chipSelectPin.low(); // Select slave
|
||||
// When using SPI all addresses are shifted one bit left in the "SPI address byte" (section 8.1.2.3)
|
||||
_spiClass.transfer(reg << 1); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
_spiClass.transfer(value);
|
||||
_chipSelectPin.high(); // Release slave again
|
||||
_spiClass.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_WriteRegister()
|
||||
|
||||
/**
|
||||
* Writes a number of bytes to the specified register in the MFRC522DriverSPI chip.
|
||||
* The interface is described in the datasheet section 8.1.2.
|
||||
*/
|
||||
void MFRC522DriverSPI::PCD_WriteRegister(const PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
|
||||
const byte count, ///< The number of bytes to write to the register.
|
||||
byte *const values ///< The values to write. Byte array.
|
||||
) {
|
||||
_spiClass.beginTransaction(_spiSettings); // Set the settings to work with SPI bus
|
||||
_chipSelectPin.low(); // Select slave
|
||||
_spiClass.transfer(reg << 1); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
for(byte index = 0; index < count; index++) {
|
||||
_spiClass.transfer(values[index]);
|
||||
}
|
||||
_chipSelectPin.high(); // Release slave again
|
||||
_spiClass.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_WriteRegister()
|
||||
|
||||
/**
|
||||
* Reads a byte from the specified register in the MFRC522DriverSPI chip.
|
||||
* The interface is described in the datasheet section 8.1.2.
|
||||
*/
|
||||
byte MFRC522DriverSPI::PCD_ReadRegister(const PCD_Register reg ///< The register to read from. One of the PCD_Register enums.
|
||||
) {
|
||||
byte value;
|
||||
_spiClass.beginTransaction(_spiSettings); // Set the settings to work with SPI bus
|
||||
_chipSelectPin.low(); // Select slave
|
||||
_spiClass.transfer((byte)0x80 | (reg << 1)); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
value = _spiClass.transfer(0); // Read the value back. Send 0 to stop reading.
|
||||
_chipSelectPin.high(); // Release slave again
|
||||
_spiClass.endTransaction(); // Stop using the SPI bus
|
||||
return value;
|
||||
} // End PCD_ReadRegister()
|
||||
|
||||
/**
|
||||
* Reads a number of bytes from the specified register in the MFRC522DriverSPI chip.
|
||||
* The interface is described in the datasheet section 8.1.2.
|
||||
*/
|
||||
void MFRC522DriverSPI::PCD_ReadRegister(const PCD_Register reg, ///< The register to read from. One of the PCD_Register enums.
|
||||
const byte count, ///< The number of bytes to read.
|
||||
byte *const values, ///< Byte array to store the values in.
|
||||
const byte rxAlign ///< Only bit positions rxAlign..7 in values[0] are updated.
|
||||
) {
|
||||
if(count == 0) {
|
||||
return;
|
||||
}
|
||||
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
|
||||
byte address = (byte)0x80 | (reg << 1); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
byte index = 0; // Index in values array.
|
||||
_spiClass.beginTransaction(_spiSettings); // Set the settings to work with SPI bus
|
||||
_chipSelectPin.low(); // Select slave
|
||||
//count--; // One read is performed outside of the loop // TODO is this correct?
|
||||
_spiClass.transfer(address); // Tell MFRC522 which address we want to read
|
||||
if(rxAlign) { // Only update bit positions rxAlign..7 in values[0]
|
||||
// Create bit mask for bit positions rxAlign..7
|
||||
byte mask = (byte)(0xFF << rxAlign) & 0xFF;
|
||||
// Read value and tell that we want to read the same address again.
|
||||
byte value = _spiClass.transfer(address);
|
||||
// Apply mask to both current value of values[0] and the new data in value.
|
||||
values[0] = (values[0] & ~mask) | (value & mask);
|
||||
index++;
|
||||
}
|
||||
//while (index < count) { // changed because count changed to const
|
||||
while(index < count-1) {
|
||||
values[index] = _spiClass.transfer(address); // Read value and tell that we want to read the same address again.
|
||||
index++;
|
||||
}
|
||||
values[index] = _spiClass.transfer(0); // Read the final byte. Send 0 to stop reading.
|
||||
_chipSelectPin.high(); // Release slave again
|
||||
_spiClass.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_ReadRegister()
|
||||
|
||||
43
lib/Arduino_MFRC522v2-master/src/MFRC522DriverSPI.h
Normal file
43
lib/Arduino_MFRC522v2-master/src/MFRC522DriverSPI.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <SPI.h>
|
||||
#include <MFRC522Driver.h>
|
||||
#include <MFRC522DriverPin.h>
|
||||
|
||||
class MFRC522DriverSPI : public MFRC522Driver {
|
||||
public:
|
||||
//using PCD_Register = MFRC522Constants::PCD_Register;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for setting up the Arduino.
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool init() override;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522.
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_WriteRegister(const PCD_Register reg, const byte value) override;
|
||||
void PCD_WriteRegister(const PCD_Register reg, const byte count, byte *const values) override;
|
||||
byte PCD_ReadRegister(const PCD_Register reg) override;
|
||||
void PCD_ReadRegister(const PCD_Register reg, const byte count, byte *const values, const byte rxAlign = 0) override;
|
||||
|
||||
|
||||
// Advanced init with custom chip select method, e.g. with i2c port expander or multiplexer.
|
||||
MFRC522DriverSPI(MFRC522DriverPin &chipSelectPin,
|
||||
SPIClass &spiClass = SPI,
|
||||
const SPISettings spiSettings = SPISettings(4000000u /* 4MHz */, MSBFIRST, SPI_MODE0)
|
||||
) : MFRC522Driver(),
|
||||
_chipSelectPin(chipSelectPin),
|
||||
_spiClass(spiClass),
|
||||
_spiSettings(spiSettings) {};
|
||||
|
||||
protected:
|
||||
// Pins.
|
||||
//byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
||||
MFRC522DriverPin &_chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
||||
|
||||
// SPI communication.
|
||||
SPIClass &_spiClass; // SPI class which abstracts hardware.
|
||||
const SPISettings _spiSettings; // SPI settings.
|
||||
};
|
||||
210
lib/Arduino_MFRC522v2-master/src/MFRC522Hack.cpp
Normal file
210
lib/Arduino_MFRC522v2-master/src/MFRC522Hack.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#include "MFRC522Hack.h"
|
||||
|
||||
/**
|
||||
* Performs the "magic sequence" needed to get Chinese UID changeable
|
||||
* Mifare cards to allow writing to sector 0, where the card UID is stored.
|
||||
*
|
||||
* Note that you do not need to have selected the card through REQA or WUPA,
|
||||
* this sequence works immediately when the card is in the reader vicinity.
|
||||
* This means you can use this method even on "bricked" cards that your reader does
|
||||
* not recognise anymore (see MFRC522Hack::MIFARE_UnbrickUidSector).
|
||||
*
|
||||
* Of course with non-bricked devices, you're free to select them before calling this function.
|
||||
*/
|
||||
bool MFRC522Hack::MIFARE_OpenUidBackdoor(void) const {
|
||||
// Magic sequence:
|
||||
// > 50 00 57 CD (HALT + CRC)
|
||||
// > 40 (7 bits only)
|
||||
// < A (4 bits only)
|
||||
// > 43
|
||||
// < A (4 bits only)
|
||||
// Then you can write to sector 0 without authenticating
|
||||
|
||||
_device.PICC_HaltA(); // 50 00 57 CD
|
||||
|
||||
byte cmd = 0x40;
|
||||
byte validBits = 7; // Our command is only 7 bits. After receiving card response, this will contain amount of valid response bits.
|
||||
byte response[32] = {0}; // Card's response is written here.
|
||||
byte received = sizeof(response);
|
||||
|
||||
StatusCode status = _device.PCD_TransceiveData(&cmd, (byte)1, response, &received, &validBits, (byte)0, false); // 40
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(_logErrors) {
|
||||
_logPrint->println(
|
||||
F("Card did not respond to 0x40 after HALT command. Are you sure it is a UID changeable one?"));
|
||||
_logPrint->print(F("Error name: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(received != 1 || response[0] != 0x0A) {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("Got bad response on backdoor 0x40 command: "));
|
||||
_logPrint->print(response[0], HEX);
|
||||
_logPrint->print(F(" ("));
|
||||
_logPrint->print(validBits);
|
||||
_logPrint->print(F(" valid bits)\r\n"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd = 0x43;
|
||||
validBits = 8;
|
||||
status = _device.PCD_TransceiveData(&cmd, (byte)1, response, &received, &validBits, (byte)0, false); // 43
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(_logErrors) {
|
||||
_logPrint->println(F("Error in communication at command 0x43, after successfully executing 0x40"));
|
||||
_logPrint->print(F("Error name: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(received != 1 || response[0] != 0x0A) {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("Got bad response on backdoor 0x43 command: "));
|
||||
_logPrint->print(response[0], HEX);
|
||||
_logPrint->print(F(" ("));
|
||||
_logPrint->print(validBits);
|
||||
_logPrint->print(F(" valid bits)\r\n"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// You can now write to sector 0 without authenticating!
|
||||
return true;
|
||||
} // End MIFARE_OpenUidBackdoor()
|
||||
|
||||
/**
|
||||
* Reads entire block 0, including all manufacturer data, and overwrites
|
||||
* that block with the new UID, a freshly calculated BCC, and the original
|
||||
* manufacturer data.
|
||||
*
|
||||
* Notes:
|
||||
* The common default KEY A is 0xFFFFFFFFFFFF.
|
||||
* Make sure to have selected the card before this function is called.
|
||||
*/
|
||||
bool MFRC522Hack::MIFARE_SetUid(const byte *const newUid, const byte uidSize, MFRC522::MIFARE_Key &key, const bool withBackdoor) const {
|
||||
|
||||
// UID + BCC byte can not be larger than 16 together
|
||||
if(!newUid || !uidSize || uidSize > 15) {
|
||||
if(_logErrors) {
|
||||
_logPrint->println(F("New UID buffer empty, size 0, or size > 15 given"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Authenticate for reading
|
||||
StatusCode status = _device.PCD_Authenticate(PICC_Command::PICC_CMD_MF_AUTH_KEY_A, (byte)1, &key, &(_device.uid));
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(status == StatusCode::STATUS_TIMEOUT) {
|
||||
// We get a read timeout if no card is selected yet, so let's select one.
|
||||
|
||||
// Wake the card up again if sleeping.
|
||||
// byte atqa_answer[2];
|
||||
// byte atqa_size = 2;
|
||||
// PICC_WakeupA(atqa_answer, &atqa_size);
|
||||
|
||||
if(!_device.PICC_IsNewCardPresent() || !_device.PICC_ReadCardSerial()) {
|
||||
_logPrint->println(F("No card was previously selected, and none are available. Failed to set UID."));
|
||||
return false;
|
||||
}
|
||||
|
||||
status = _device.PCD_Authenticate(PICC_Command::PICC_CMD_MF_AUTH_KEY_A, (byte)1, &key, &(_device.uid));
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
// We tried, time to give up
|
||||
if(_logErrors) {
|
||||
_logPrint->println(F("Failed to authenticate to card for reading, could not set UID: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("PCD_Authenticate() failed: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Read block 0
|
||||
byte block0_buffer[18];
|
||||
byte byteCount = sizeof(block0_buffer);
|
||||
|
||||
status = _device.MIFARE_Read((byte)0, block0_buffer, &byteCount);
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("MIFARE_Read() failed: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
_logPrint->println(F("Are you sure your KEY A for sector 0 is correct?"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write new UID to the data we just read, and calculate BCC byte.
|
||||
byte bcc = 0;
|
||||
|
||||
for(uint8_t i = 0; i < uidSize; i++) {
|
||||
block0_buffer[i] = newUid[i];
|
||||
bcc ^= newUid[i];
|
||||
}
|
||||
|
||||
// Write BCC byte to buffer.
|
||||
block0_buffer[uidSize] = bcc;
|
||||
|
||||
// Some cards do not need the backdoor. They are writeable directly.
|
||||
if(withBackdoor) {
|
||||
// Stop encrypted traffic so we can send raw bytes.
|
||||
_device.PCD_StopCrypto1();
|
||||
|
||||
// Activate UID backdoor.
|
||||
if(!MIFARE_OpenUidBackdoor()) {
|
||||
if(_logErrors) {
|
||||
_logPrint->println(F("Activating the UID backdoor failed."));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write modified block 0 back to card.
|
||||
status = _device.MIFARE_Write((byte)0, block0_buffer, (byte)16);
|
||||
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("MIFARE_Write() failed: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some cards do not need the backdoor. They are writeable directly.
|
||||
if(withBackdoor) {
|
||||
// Wake the card up again.
|
||||
byte atqa_answer[2];
|
||||
byte atqa_size = 2;
|
||||
_device.PICC_WakeupA(atqa_answer, &atqa_size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets entire sector 0 to zeroes, so the card can be read again by readers.
|
||||
*/
|
||||
bool MFRC522Hack::MIFARE_UnbrickUidSector(void) const {
|
||||
MIFARE_OpenUidBackdoor();
|
||||
|
||||
byte block0_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
// Write modified block 0 back to card.
|
||||
StatusCode status = _device.MIFARE_Write((byte)0, block0_buffer, (byte)16);
|
||||
if(status != StatusCode::STATUS_OK) {
|
||||
if(_logErrors) {
|
||||
_logPrint->print(F("MIFARE_Write() failed: "));
|
||||
_logPrint->println(MFRC522Debug::GetStatusCodeName(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
26
lib/Arduino_MFRC522v2-master/src/MFRC522Hack.h
Normal file
26
lib/Arduino_MFRC522v2-master/src/MFRC522Hack.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522Debug.h>
|
||||
|
||||
class MFRC522Hack {
|
||||
private:
|
||||
using StatusCode = MFRC522Constants::StatusCode;
|
||||
using PICC_Command = MFRC522Constants::PICC_Command;
|
||||
MFRC522 &_device;
|
||||
bool _logErrors;
|
||||
Print *_logPrint; // Injected Arduino API could be replaced by void* if required.
|
||||
|
||||
public:
|
||||
MFRC522Hack(MFRC522 &device, const bool logErrors, Print *logPrint = nullptr) : _device(device), _logPrint(logPrint) {
|
||||
_logErrors = logErrors && (logPrint != nullptr);
|
||||
};
|
||||
|
||||
bool MIFARE_OpenUidBackdoor(void) const;
|
||||
|
||||
bool MIFARE_SetUid(const byte *const newUid, const byte uidSize, MFRC522::MIFARE_Key &key, bool withBackdoor) const;
|
||||
|
||||
bool MIFARE_UnbrickUidSector(void) const;
|
||||
};
|
||||
1280
lib/Arduino_MFRC522v2-master/src/MFRC522v2.cpp
Normal file
1280
lib/Arduino_MFRC522v2-master/src/MFRC522v2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
203
lib/Arduino_MFRC522v2-master/src/MFRC522v2.h
Normal file
203
lib/Arduino_MFRC522v2-master/src/MFRC522v2.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
/**
|
||||
* Library to use Arduino MFRC522 module.
|
||||
*
|
||||
* @authors Dr.Leong, Miguel Balboa, Søren Thing Andersen, Tom Clement, many more! See GitLog.
|
||||
*
|
||||
* Please read this file for an overview and then MFRC522v2.cpp for comments on the specific functions.
|
||||
*/
|
||||
#ifndef MFRC522_h
|
||||
#define MFRC522_h
|
||||
|
||||
#include <require_cpp11.h>
|
||||
// Enable integer limits
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522Constants.h>
|
||||
#include <MFRC522Driver.h>
|
||||
|
||||
|
||||
// Firmware data for self-test
|
||||
// Reference values based on firmware version
|
||||
// Hint: if needed, you can remove unused self-test data to save flash memory
|
||||
//
|
||||
// Version 0.0 (0x90)
|
||||
// Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 self-test
|
||||
const byte MFRC522_firmware_referenceV0_0[]
|
||||
PROGMEM = {
|
||||
0x00, 0x87, 0x98, 0x0f, 0x49, 0xFF, 0x07, 0x19,
|
||||
0xBF, 0x22, 0x30, 0x49, 0x59, 0x63, 0xAD, 0xCA,
|
||||
0x7F, 0xE3, 0x4E, 0x03, 0x5C, 0x4E, 0x49, 0x50,
|
||||
0x47, 0x9A, 0x37, 0x61, 0xE7, 0xE2, 0xC6, 0x2E,
|
||||
0x75, 0x5A, 0xED, 0x04, 0x3D, 0x02, 0x4B, 0x78,
|
||||
0x32, 0xFF, 0x58, 0x3B, 0x7C, 0xE9, 0x00, 0x94,
|
||||
0xB4, 0x4A, 0x59, 0x5B, 0xFD, 0xC9, 0x29, 0xDF,
|
||||
0x35, 0x96, 0x98, 0x9E, 0x4F, 0x30, 0x32, 0x8D
|
||||
};
|
||||
// Version 1.0 (0x91)
|
||||
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
|
||||
const byte MFRC522_firmware_referenceV1_0[]
|
||||
PROGMEM = {
|
||||
0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
|
||||
0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
|
||||
0x10, 0xE6, 0xD2, 0xAA, 0x5E, 0xA1, 0x3E, 0x5A,
|
||||
0x14, 0xAF, 0x30, 0x61, 0xC9, 0x70, 0xDB, 0x2E,
|
||||
0x64, 0x22, 0x72, 0xB5, 0xBD, 0x65, 0xF4, 0xEC,
|
||||
0x22, 0xBC, 0xD3, 0x72, 0x35, 0xCD, 0xAA, 0x41,
|
||||
0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
|
||||
0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
|
||||
};
|
||||
// Version 2.0 (0x92)
|
||||
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
|
||||
const byte MFRC522_firmware_referenceV2_0[]
|
||||
PROGMEM = {
|
||||
0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
|
||||
0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
|
||||
0x9D, 0x3B, 0xA7, 0x00, 0x21, 0x5B, 0x89, 0x82,
|
||||
0x51, 0x3A, 0xEB, 0x02, 0x0C, 0xA5, 0x00, 0x49,
|
||||
0x7C, 0x84, 0x4D, 0xB3, 0xCC, 0xD2, 0x1B, 0x81,
|
||||
0x5D, 0x48, 0x76, 0xD5, 0x71, 0x61, 0x21, 0xA9,
|
||||
0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
|
||||
0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
|
||||
};
|
||||
// Clone
|
||||
// Fudan Semiconductor FM17522 (0x88)
|
||||
const byte FM17522_firmware_reference88[]
|
||||
PROGMEM = {
|
||||
0x00, 0xD6, 0x78, 0x8C, 0xE2, 0xAA, 0x0C, 0x18,
|
||||
0x2A, 0xB8, 0x7A, 0x7F, 0xD3, 0x6A, 0xCF, 0x0B,
|
||||
0xB1, 0x37, 0x63, 0x4B, 0x69, 0xAE, 0x91, 0xC7,
|
||||
0xC3, 0x97, 0xAE, 0x77, 0xF4, 0x37, 0xD7, 0x9B,
|
||||
0x7C, 0xF5, 0x3C, 0x11, 0x8F, 0x15, 0xC3, 0xD7,
|
||||
0xC1, 0x5B, 0x00, 0x2A, 0xD0, 0x75, 0xDE, 0x9E,
|
||||
0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
|
||||
0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
|
||||
};
|
||||
// Another "FM17522" ic form Aliexpress
|
||||
const byte FM17522_firmware_referenceB2[]
|
||||
PROGMEM = {
|
||||
0x00, 0xeb, 0x44, 0x85, 0xfa, 0x9a, 0x78, 0x01,
|
||||
0x74, 0xe5, 0x1c, 0x7a, 0x0a, 0xa0, 0x71, 0xe1,
|
||||
0xf3, 0xfa, 0x96, 0x6d, 0x28, 0xa1, 0x34, 0x46,
|
||||
0x3a, 0x1c, 0x32, 0x96, 0xb9, 0xe6, 0x44, 0x87,
|
||||
0x0a, 0x45, 0x98, 0xa9, 0x36, 0x60, 0x89, 0x0f,
|
||||
0x06, 0x9b, 0x7b, 0x17, 0xb3, 0x0c, 0x1a, 0x6c,
|
||||
0x1a, 0xae, 0x2c, 0xac, 0x0e, 0x6f, 0x2e, 0x02,
|
||||
0x2b, 0xcb, 0x8a, 0xb2, 0x45, 0xdd, 0x7e, 0x3c
|
||||
};
|
||||
// Fudan Semiconductor FM17522E (0x89)
|
||||
const byte FM17522E_firmware_reference[]
|
||||
PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x00, 0x04, 0xcc, 0xc8, 0x00,
|
||||
0x10, 0x04, 0x00, 0xc0, 0x00, 0x90, 0x00, 0x20,
|
||||
0x00, 0x00, 0x23, 0x00, 0x38, 0x06, 0x01, 0x33,
|
||||
0x98, 0xf3, 0x80, 0x06, 0xc0, 0xf9, 0x80, 0x08,
|
||||
0x27, 0x04, 0x23, 0x82, 0x21, 0x12, 0xf9, 0xc7
|
||||
};
|
||||
|
||||
class MFRC522 {
|
||||
public:
|
||||
//using PCD_Register = MFRC522Constants::PCD_Register;
|
||||
using PCD_Register = MFRC522Constants::PCD_Register;
|
||||
using PCD_RxGain = MFRC522Constants::PCD_RxGain;
|
||||
using PICC_Command = MFRC522Constants::PICC_Command;
|
||||
using MIFARE_Misc = MFRC522Constants::MIFARE_Misc;
|
||||
using PICC_Type = MFRC522Constants::PICC_Type;
|
||||
using StatusCode = MFRC522Constants::StatusCode;
|
||||
using PCD_Command = MFRC522Constants::PCD_Command;
|
||||
using PCD_Version = MFRC522Constants::PCD_Version;
|
||||
using Uid = MFRC522Constants::Uid;
|
||||
using MIFARE_Key = MFRC522Constants::MIFARE_Key;
|
||||
|
||||
// Size of the MFRC522 FIFO
|
||||
static constexpr byte FIFO_SIZE = 64; // The FIFO is 64 bytes.
|
||||
|
||||
// Member variables
|
||||
Uid uid; // Used by PICC_ReadCardSerial().
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for setting up the Arduino
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
MFRC522(MFRC522Driver &driver)
|
||||
: _driver(driver) {};
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_SetRegisterBitMask(PCD_Register reg, byte mask);
|
||||
void PCD_ClearRegisterBitMask(PCD_Register reg, byte mask);
|
||||
StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for manipulating the MFRC522
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
bool PCD_Init();
|
||||
void PCD_Reset();
|
||||
void PCD_AntennaOn();
|
||||
void PCD_AntennaOff();
|
||||
byte PCD_GetAntennaGain();
|
||||
void PCD_SetAntennaGain(byte mask);
|
||||
|
||||
PCD_Version PCD_GetVersion();
|
||||
bool PCD_PerformSelfTest();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Power control functions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_SoftPowerDown();
|
||||
void PCD_SoftPowerUp();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for communicating with PICCs
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
|
||||
StatusCode PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = nullptr, byte *backLen = nullptr, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
|
||||
StatusCode PICC_RequestA(byte *bufferATQA, byte *bufferSize);
|
||||
StatusCode PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
|
||||
StatusCode PICC_REQA_or_WUPA(byte command, byte *bufferATQA, byte *bufferSize);
|
||||
virtual StatusCode PICC_Select(Uid *uid, byte validBits = 0);
|
||||
StatusCode PICC_HaltA();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for communicating with MIFARE PICCs
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
|
||||
void PCD_StopCrypto1();
|
||||
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
|
||||
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
|
||||
StatusCode MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
|
||||
StatusCode MIFARE_Decrement(byte blockAddr, int32_t delta);
|
||||
StatusCode MIFARE_Increment(byte blockAddr, int32_t delta);
|
||||
StatusCode MIFARE_Restore(byte blockAddr);
|
||||
StatusCode MIFARE_Transfer(byte blockAddr);
|
||||
StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value);
|
||||
StatusCode MIFARE_SetValue(byte blockAddr, int32_t value);
|
||||
StatusCode PCD_NTAG216_AUTH(const byte password[4], byte pACK[]);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Support functions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false);
|
||||
static PICC_Type PICC_GetType(byte sak);
|
||||
|
||||
// Advanced functions for MIFARE
|
||||
void MIFARE_CalculateAccessBits(byte accessBitBuffer[3], const byte g0, const byte g1, const byte g2, const byte g3) const;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convenience functions - does not add extra functionality
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool PICC_IsNewCardPresent();
|
||||
virtual bool PICC_ReadCardSerial();
|
||||
|
||||
protected:
|
||||
MFRC522Driver &_driver;
|
||||
|
||||
// Functions for communicating with MIFARE PICCs
|
||||
StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, int32_t data);
|
||||
};
|
||||
|
||||
#endif
|
||||
10
lib/Arduino_MFRC522v2-master/src/require_cpp11.h
Normal file
10
lib/Arduino_MFRC522v2-master/src/require_cpp11.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1 */
|
||||
/**
|
||||
* Copyright (c) 2016 by Ludwig Grill (www.rotzbua.de)
|
||||
* Throws error if c++11 is not supported
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#error "This library needs at least a C++11 compliant compiler, maybe compiler argument for C++11 support is missing or if you use Arduino IDE upgrade to version >=1.6.6"
|
||||
#endif
|
||||
7
lib/NTPClient-master/.codespellrc
Normal file
7
lib/NTPClient-master/.codespellrc
Normal file
@@ -0,0 +1,7 @@
|
||||
# See: https://github.com/codespell-project/codespell#using-a-config-file
|
||||
[codespell]
|
||||
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
|
||||
ignore-words-list = ,
|
||||
check-filenames =
|
||||
check-hidden =
|
||||
skip = ./.git
|
||||
10
lib/NTPClient-master/.github/dependabot.yml
vendored
Normal file
10
lib/NTPClient-master/.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#about-the-dependabotyml-file
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
# Configure check for outdated GitHub Actions actions in workflows.
|
||||
# See: https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot
|
||||
- package-ecosystem: github-actions
|
||||
directory: / # Check the repository's workflows under /.github/workflows/
|
||||
schedule:
|
||||
interval: daily
|
||||
28
lib/NTPClient-master/.github/workflows/check-arduino.yml
vendored
Normal file
28
lib/NTPClient-master/.github/workflows/check-arduino.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Check Arduino
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
# Run every Tuesday at 8 AM UTC to catch breakage caused by new rules added to Arduino Lint.
|
||||
- cron: "0 8 * * TUE"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Arduino Lint
|
||||
uses: arduino/arduino-lint-action@v2
|
||||
with:
|
||||
compliance: specification
|
||||
library-manager: update
|
||||
# Always use this setting for official repositories. Remove for 3rd party projects.
|
||||
official: true
|
||||
project-type: library
|
||||
71
lib/NTPClient-master/.github/workflows/compile-examples.yml
vendored
Normal file
71
lib/NTPClient-master/.github/workflows/compile-examples.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: Compile Examples
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/compile-examples.yml"
|
||||
- "examples/**"
|
||||
- "**.c"
|
||||
- "**.cpp"
|
||||
- "**.h"
|
||||
- "*.S"
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/compile-examples.yml"
|
||||
- "examples/**"
|
||||
- "**.c"
|
||||
- "**.cpp"
|
||||
- "**.h"
|
||||
- "*.S"
|
||||
schedule:
|
||||
# Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms).
|
||||
- cron: "0 8 * * TUE"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.board.fqbn }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
SKETCHES_REPORTS_PATH: sketches-reports
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
board:
|
||||
- fqbn: esp8266:esp8266:huzzah
|
||||
platforms: |
|
||||
- name: esp8266:esp8266
|
||||
source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||
artifact-name-suffix: esp8266-esp8266-huzzah
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Compile examples
|
||||
uses: arduino/compile-sketches@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fqbn: ${{ matrix.board.fqbn }}
|
||||
platforms: ${{ matrix.board.platforms }}
|
||||
libraries: |
|
||||
# Install the library from the local path.
|
||||
- source-path: ./
|
||||
# Additional library dependencies can be listed here.
|
||||
# See: https://github.com/arduino/compile-sketches#libraries
|
||||
sketch-paths: |
|
||||
- examples
|
||||
enable-deltas-report: true
|
||||
sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
|
||||
|
||||
- name: Save sketches report as workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
path: ${{ env.SKETCHES_REPORTS_PATH }}
|
||||
name: sketches-report-${{ matrix.board.artifact-name-suffix }}
|
||||
24
lib/NTPClient-master/.github/workflows/report-size-deltas.yml
vendored
Normal file
24
lib/NTPClient-master/.github/workflows/report-size-deltas.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Report Size Deltas
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/report-size-deltas.yml"
|
||||
schedule:
|
||||
# Run at the minimum interval allowed by GitHub Actions.
|
||||
# Note: GitHub Actions periodically has outages which result in workflow failures.
|
||||
# In this event, the workflows will start passing again once the service recovers.
|
||||
- cron: "*/5 * * * *"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
report:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Comment size deltas reports to PRs
|
||||
uses: arduino/report-size-deltas@v1
|
||||
with:
|
||||
# Regex matching the names of the workflow artifacts created by the "Compile Examples" workflow
|
||||
sketches-reports-source: ^sketches-report-.+
|
||||
22
lib/NTPClient-master/.github/workflows/spell-check.yml
vendored
Normal file
22
lib/NTPClient-master/.github/workflows/spell-check.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Spell Check
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
# Run every Tuesday at 8 AM UTC to catch new misspelling detections resulting from dictionary updates.
|
||||
- cron: "0 8 * * TUE"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spell check
|
||||
uses: codespell-project/actions-codespell@master
|
||||
138
lib/NTPClient-master/.github/workflows/sync-labels.yml
vendored
Normal file
138
lib/NTPClient-master/.github/workflows/sync-labels.yml
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/sync-labels.md
|
||||
name: Sync Labels
|
||||
|
||||
# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/sync-labels.ya?ml"
|
||||
- ".github/label-configuration-files/*.ya?ml"
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/sync-labels.ya?ml"
|
||||
- ".github/label-configuration-files/*.ya?ml"
|
||||
schedule:
|
||||
# Run daily at 8 AM UTC to sync with changes to shared label configurations.
|
||||
- cron: "0 8 * * *"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
env:
|
||||
CONFIGURATIONS_FOLDER: .github/label-configuration-files
|
||||
CONFIGURATIONS_ARTIFACT: label-configuration-files
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download JSON schema for labels configuration file
|
||||
id: download-schema
|
||||
uses: carlosperate/download-file-action@v2
|
||||
with:
|
||||
file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json
|
||||
location: ${{ runner.temp }}/label-configuration-schema
|
||||
|
||||
- name: Install JSON schema validator
|
||||
run: |
|
||||
sudo npm install \
|
||||
--global \
|
||||
ajv-cli \
|
||||
ajv-formats
|
||||
|
||||
- name: Validate local labels configuration
|
||||
run: |
|
||||
# See: https://github.com/ajv-validator/ajv-cli#readme
|
||||
ajv validate \
|
||||
--all-errors \
|
||||
-c ajv-formats \
|
||||
-s "${{ steps.download-schema.outputs.file-path }}" \
|
||||
-d "${{ env.CONFIGURATIONS_FOLDER }}/*.{yml,yaml}"
|
||||
|
||||
download:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
filename:
|
||||
# Filenames of the shared configurations to apply to the repository in addition to the local configuration.
|
||||
# https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/sync-labels
|
||||
- universal.yml
|
||||
|
||||
steps:
|
||||
- name: Download
|
||||
uses: carlosperate/download-file-action@v2
|
||||
with:
|
||||
file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }}
|
||||
|
||||
- name: Pass configuration files to next job via workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: |
|
||||
*.yaml
|
||||
*.yml
|
||||
if-no-files-found: error
|
||||
name: ${{ env.CONFIGURATIONS_ARTIFACT }}
|
||||
|
||||
sync:
|
||||
needs: download
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set environment variables
|
||||
run: |
|
||||
# See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
|
||||
echo "MERGED_CONFIGURATION_PATH=${{ runner.temp }}/labels.yml" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Determine whether to dry run
|
||||
id: dry-run
|
||||
if: >
|
||||
github.event_name == 'pull_request' ||
|
||||
(
|
||||
(
|
||||
github.event_name == 'push' ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
) &&
|
||||
github.ref != format('refs/heads/{0}', github.event.repository.default_branch)
|
||||
)
|
||||
run: |
|
||||
# Use of this flag in the github-label-sync command will cause it to only check the validity of the
|
||||
# configuration.
|
||||
echo "::set-output name=flag::--dry-run"
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download configuration files artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ env.CONFIGURATIONS_ARTIFACT }}
|
||||
path: ${{ env.CONFIGURATIONS_FOLDER }}
|
||||
|
||||
- name: Remove unneeded artifact
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
with:
|
||||
name: ${{ env.CONFIGURATIONS_ARTIFACT }}
|
||||
|
||||
- name: Merge label configuration files
|
||||
run: |
|
||||
# Merge all configuration files
|
||||
shopt -s extglob
|
||||
cat "${{ env.CONFIGURATIONS_FOLDER }}"/*.@(yml|yaml) > "${{ env.MERGED_CONFIGURATION_PATH }}"
|
||||
|
||||
- name: Install github-label-sync
|
||||
run: sudo npm install --global github-label-sync
|
||||
|
||||
- name: Sync labels
|
||||
env:
|
||||
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# See: https://github.com/Financial-Times/github-label-sync
|
||||
github-label-sync \
|
||||
--labels "${{ env.MERGED_CONFIGURATION_PATH }}" \
|
||||
${{ steps.dry-run.outputs.flag }} \
|
||||
${{ github.repository }}
|
||||
15
lib/NTPClient-master/CHANGELOG
Normal file
15
lib/NTPClient-master/CHANGELOG
Normal file
@@ -0,0 +1,15 @@
|
||||
NTPClient 3.1.0 - 2016.05.31
|
||||
|
||||
* Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli
|
||||
|
||||
NTPClient 3.0.0 - 2016.04.19
|
||||
|
||||
* Constructors now require UDP instance argument, to add support for non-ESP8266 boards
|
||||
* Added optional begin API to override default local port
|
||||
* Added end API to close UDP socket
|
||||
* Changed return type of update and forceUpdate APIs to bool, and return success or failure
|
||||
* Change return type of getDay, getHours, getMinutes, and getSeconds to int
|
||||
|
||||
Older
|
||||
|
||||
* Changes not recorded
|
||||
212
lib/NTPClient-master/NTPClient.cpp
Executable file
212
lib/NTPClient-master/NTPClient.cpp
Executable file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2015 by Fabrice Weinberg
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "NTPClient.h"
|
||||
|
||||
NTPClient::NTPClient(UDP& udp) {
|
||||
this->_udp = &udp;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, long timeOffset) {
|
||||
this->_udp = &udp;
|
||||
this->_timeOffset = timeOffset;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, const char* poolServerName) {
|
||||
this->_udp = &udp;
|
||||
this->_poolServerName = poolServerName;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP) {
|
||||
this->_udp = &udp;
|
||||
this->_poolServerIP = poolServerIP;
|
||||
this->_poolServerName = NULL;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset) {
|
||||
this->_udp = &udp;
|
||||
this->_timeOffset = timeOffset;
|
||||
this->_poolServerName = poolServerName;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset){
|
||||
this->_udp = &udp;
|
||||
this->_timeOffset = timeOffset;
|
||||
this->_poolServerIP = poolServerIP;
|
||||
this->_poolServerName = NULL;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval) {
|
||||
this->_udp = &udp;
|
||||
this->_timeOffset = timeOffset;
|
||||
this->_poolServerName = poolServerName;
|
||||
this->_updateInterval = updateInterval;
|
||||
}
|
||||
|
||||
NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval) {
|
||||
this->_udp = &udp;
|
||||
this->_timeOffset = timeOffset;
|
||||
this->_poolServerIP = poolServerIP;
|
||||
this->_poolServerName = NULL;
|
||||
this->_updateInterval = updateInterval;
|
||||
}
|
||||
|
||||
void NTPClient::begin() {
|
||||
this->begin(NTP_DEFAULT_LOCAL_PORT);
|
||||
}
|
||||
|
||||
void NTPClient::begin(unsigned int port) {
|
||||
this->_port = port;
|
||||
|
||||
this->_udp->begin(this->_port);
|
||||
|
||||
this->_udpSetup = true;
|
||||
}
|
||||
|
||||
bool NTPClient::forceUpdate() {
|
||||
#ifdef DEBUG_NTPClient
|
||||
Serial.println("Update from NTP Server");
|
||||
#endif
|
||||
|
||||
// flush any existing packets
|
||||
while(this->_udp->parsePacket() != 0)
|
||||
this->_udp->flush();
|
||||
|
||||
this->sendNTPPacket();
|
||||
|
||||
// Wait till data is there or timeout...
|
||||
byte timeout = 0;
|
||||
int cb = 0;
|
||||
do {
|
||||
delay ( 10 );
|
||||
cb = this->_udp->parsePacket();
|
||||
if (timeout > 100) return false; // timeout after 1000 ms
|
||||
timeout++;
|
||||
} while (cb == 0);
|
||||
|
||||
this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time
|
||||
|
||||
this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE);
|
||||
|
||||
unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
|
||||
unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
|
||||
// combine the four bytes (two words) into a long integer
|
||||
// this is NTP time (seconds since Jan 1 1900):
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
|
||||
this->_currentEpoc = secsSince1900 - SEVENZYYEARS;
|
||||
|
||||
return true; // return true after successful update
|
||||
}
|
||||
|
||||
bool NTPClient::update() {
|
||||
if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval
|
||||
|| this->_lastUpdate == 0) { // Update if there was no update yet.
|
||||
if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed
|
||||
return this->forceUpdate();
|
||||
}
|
||||
return false; // return false if update does not occur
|
||||
}
|
||||
|
||||
bool NTPClient::isTimeSet() const {
|
||||
return (this->_lastUpdate != 0); // returns true if the time has been set, else false
|
||||
}
|
||||
|
||||
unsigned long NTPClient::getEpochTime() const {
|
||||
return this->_timeOffset + // User offset
|
||||
this->_currentEpoc + // Epoch returned by the NTP server
|
||||
((millis() - this->_lastUpdate) / 1000); // Time since last update
|
||||
}
|
||||
|
||||
int NTPClient::getDay() const {
|
||||
return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday
|
||||
}
|
||||
int NTPClient::getHours() const {
|
||||
return ((this->getEpochTime() % 86400L) / 3600);
|
||||
}
|
||||
int NTPClient::getMinutes() const {
|
||||
return ((this->getEpochTime() % 3600) / 60);
|
||||
}
|
||||
int NTPClient::getSeconds() const {
|
||||
return (this->getEpochTime() % 60);
|
||||
}
|
||||
|
||||
String NTPClient::getFormattedTime() const {
|
||||
unsigned long rawTime = this->getEpochTime();
|
||||
unsigned long hours = (rawTime % 86400L) / 3600;
|
||||
String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);
|
||||
|
||||
unsigned long minutes = (rawTime % 3600) / 60;
|
||||
String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);
|
||||
|
||||
unsigned long seconds = rawTime % 60;
|
||||
String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);
|
||||
|
||||
return hoursStr + ":" + minuteStr + ":" + secondStr;
|
||||
}
|
||||
|
||||
void NTPClient::end() {
|
||||
this->_udp->stop();
|
||||
|
||||
this->_udpSetup = false;
|
||||
}
|
||||
|
||||
void NTPClient::setTimeOffset(int timeOffset) {
|
||||
this->_timeOffset = timeOffset;
|
||||
}
|
||||
|
||||
void NTPClient::setUpdateInterval(unsigned long updateInterval) {
|
||||
this->_updateInterval = updateInterval;
|
||||
}
|
||||
|
||||
void NTPClient::setPoolServerName(const char* poolServerName) {
|
||||
this->_poolServerName = poolServerName;
|
||||
}
|
||||
|
||||
void NTPClient::sendNTPPacket() {
|
||||
// set all bytes in the buffer to 0
|
||||
memset(this->_packetBuffer, 0, NTP_PACKET_SIZE);
|
||||
// Initialize values needed to form NTP request
|
||||
this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||
this->_packetBuffer[1] = 0; // Stratum, or type of clock
|
||||
this->_packetBuffer[2] = 6; // Polling Interval
|
||||
this->_packetBuffer[3] = 0xEC; // Peer Clock Precision
|
||||
// 8 bytes of zero for Root Delay & Root Dispersion
|
||||
this->_packetBuffer[12] = 49;
|
||||
this->_packetBuffer[13] = 0x4E;
|
||||
this->_packetBuffer[14] = 49;
|
||||
this->_packetBuffer[15] = 52;
|
||||
|
||||
// all NTP fields have been given values, now
|
||||
// you can send a packet requesting a timestamp:
|
||||
if (this->_poolServerName) {
|
||||
this->_udp->beginPacket(this->_poolServerName, 123);
|
||||
} else {
|
||||
this->_udp->beginPacket(this->_poolServerIP, 123);
|
||||
}
|
||||
this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE);
|
||||
this->_udp->endPacket();
|
||||
}
|
||||
|
||||
void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) {
|
||||
randomSeed(analogRead(0));
|
||||
this->_port = random(minValue, maxValue);
|
||||
}
|
||||
114
lib/NTPClient-master/NTPClient.h
Executable file
114
lib/NTPClient-master/NTPClient.h
Executable file
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#include <Udp.h>
|
||||
|
||||
#define SEVENZYYEARS 2208988800UL
|
||||
#define NTP_PACKET_SIZE 48
|
||||
#define NTP_DEFAULT_LOCAL_PORT 1337
|
||||
|
||||
class NTPClient {
|
||||
private:
|
||||
UDP* _udp;
|
||||
bool _udpSetup = false;
|
||||
|
||||
const char* _poolServerName = "pool.ntp.org"; // Default time server
|
||||
IPAddress _poolServerIP;
|
||||
unsigned int _port = NTP_DEFAULT_LOCAL_PORT;
|
||||
long _timeOffset = 0;
|
||||
|
||||
unsigned long _updateInterval = 60000; // In ms
|
||||
|
||||
unsigned long _currentEpoc = 0; // In s
|
||||
unsigned long _lastUpdate = 0; // In ms
|
||||
|
||||
byte _packetBuffer[NTP_PACKET_SIZE];
|
||||
|
||||
void sendNTPPacket();
|
||||
|
||||
public:
|
||||
NTPClient(UDP& udp);
|
||||
NTPClient(UDP& udp, long timeOffset);
|
||||
NTPClient(UDP& udp, const char* poolServerName);
|
||||
NTPClient(UDP& udp, const char* poolServerName, long timeOffset);
|
||||
NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval);
|
||||
NTPClient(UDP& udp, IPAddress poolServerIP);
|
||||
NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset);
|
||||
NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval);
|
||||
|
||||
/**
|
||||
* Set time server name
|
||||
*
|
||||
* @param poolServerName
|
||||
*/
|
||||
void setPoolServerName(const char* poolServerName);
|
||||
|
||||
/**
|
||||
* Set random local port
|
||||
*/
|
||||
void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535);
|
||||
|
||||
/**
|
||||
* Starts the underlying UDP client with the default local port
|
||||
*/
|
||||
void begin();
|
||||
|
||||
/**
|
||||
* Starts the underlying UDP client with the specified local port
|
||||
*/
|
||||
void begin(unsigned int port);
|
||||
|
||||
/**
|
||||
* This should be called in the main loop of your application. By default an update from the NTP Server is only
|
||||
* made every 60 seconds. This can be configured in the NTPClient constructor.
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool update();
|
||||
|
||||
/**
|
||||
* This will force the update from the NTP Server.
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool forceUpdate();
|
||||
|
||||
/**
|
||||
* This allows to check if the NTPClient successfully received a NTP packet and set the time.
|
||||
*
|
||||
* @return true if time has been set, else false
|
||||
*/
|
||||
bool isTimeSet() const;
|
||||
|
||||
int getDay() const;
|
||||
int getHours() const;
|
||||
int getMinutes() const;
|
||||
int getSeconds() const;
|
||||
|
||||
/**
|
||||
* Changes the time offset. Useful for changing timezones dynamically
|
||||
*/
|
||||
void setTimeOffset(int timeOffset);
|
||||
|
||||
/**
|
||||
* Set the update interval to another frequency. E.g. useful when the
|
||||
* timeOffset should not be set in the constructor
|
||||
*/
|
||||
void setUpdateInterval(unsigned long updateInterval);
|
||||
|
||||
/**
|
||||
* @return time formatted like `hh:mm:ss`
|
||||
*/
|
||||
String getFormattedTime() const;
|
||||
|
||||
/**
|
||||
* @return time in seconds since Jan. 1, 1970
|
||||
*/
|
||||
unsigned long getEpochTime() const;
|
||||
|
||||
/**
|
||||
* Stops the underlying UDP client
|
||||
*/
|
||||
void end();
|
||||
};
|
||||
52
lib/NTPClient-master/README.md
Normal file
52
lib/NTPClient-master/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# NTPClient
|
||||
|
||||
[](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml)
|
||||
[](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml)
|
||||
[](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml)
|
||||
|
||||
Connect to an NTP server, here is how:
|
||||
|
||||
```cpp
|
||||
#include <NTPClient.h>
|
||||
// change next line to use with another board/shield
|
||||
#include <ESP8266WiFi.h>
|
||||
//#include <WiFi.h> // for WiFi shield
|
||||
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
const char *ssid = "<SSID>";
|
||||
const char *password = "<PASSWORD>";
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
|
||||
// By default 'pool.ntp.org' is used with 60 seconds update interval and
|
||||
// no offset
|
||||
NTPClient timeClient(ntpUDP);
|
||||
|
||||
// You can specify the time server pool and the offset, (in seconds)
|
||||
// additionally you can specify the update interval (in milliseconds).
|
||||
// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while ( WiFi.status() != WL_CONNECTED ) {
|
||||
delay ( 500 );
|
||||
Serial.print ( "." );
|
||||
}
|
||||
|
||||
timeClient.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
timeClient.update();
|
||||
|
||||
Serial.println(timeClient.getFormattedTime());
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
```
|
||||
|
||||
## Function documentation
|
||||
`getEpochTime` returns the Unix epoch, which are the seconds elapsed since 00:00:00 UTC on 1 January 1970 (leap seconds are ignored, every day is treated as having 86400 seconds). **Attention**: If you have set a time offset this time offset will be added to your epoch timestamp.
|
||||
37
lib/NTPClient-master/examples/Advanced/Advanced.ino
Normal file
37
lib/NTPClient-master/examples/Advanced/Advanced.ino
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <NTPClient.h>
|
||||
// change next line to use with another board/shield
|
||||
#include <ESP8266WiFi.h>
|
||||
//#include <WiFi.h> // for WiFi shield
|
||||
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
const char *ssid = "<SSID>";
|
||||
const char *password = "<PASSWORD>";
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
|
||||
// You can specify the time server pool and the offset (in seconds, can be
|
||||
// changed later with setTimeOffset() ). Additionally you can specify the
|
||||
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
|
||||
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while ( WiFi.status() != WL_CONNECTED ) {
|
||||
delay ( 500 );
|
||||
Serial.print ( "." );
|
||||
}
|
||||
|
||||
timeClient.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
timeClient.update();
|
||||
|
||||
Serial.println(timeClient.getFormattedTime());
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
33
lib/NTPClient-master/examples/Basic/Basic.ino
Normal file
33
lib/NTPClient-master/examples/Basic/Basic.ino
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <NTPClient.h>
|
||||
// change next line to use with another board/shield
|
||||
#include <ESP8266WiFi.h>
|
||||
//#include <WiFi.h> // for WiFi shield
|
||||
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
const char *ssid = "<SSID>";
|
||||
const char *password = "<PASSWORD>";
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while ( WiFi.status() != WL_CONNECTED ) {
|
||||
delay ( 500 );
|
||||
Serial.print ( "." );
|
||||
}
|
||||
|
||||
timeClient.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
timeClient.update();
|
||||
|
||||
Serial.println(timeClient.getFormattedTime());
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
53
lib/NTPClient-master/examples/IsTimeSet/IsTimeSet.ino
Normal file
53
lib/NTPClient-master/examples/IsTimeSet/IsTimeSet.ino
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <NTPClient.h>
|
||||
// change next line to use with another board/shield
|
||||
#include <ESP8266WiFi.h>
|
||||
//#include <WiFi.h> // for WiFi shield
|
||||
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
const char *ssid = "<SSID>";
|
||||
const char *password = "<PASSWORD>";
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
// initialized to a time offset of 10 hours
|
||||
NTPClient timeClient(ntpUDP,"pool.ntp.org", 36000, 60000);
|
||||
// HH:MM:SS
|
||||
// timeClient initializes to 10:00:00 if it does not receive an NTP packet
|
||||
// before the 100ms timeout.
|
||||
// without isTimeSet() the LED would be switched on, although the time
|
||||
// was not yet set correctly.
|
||||
|
||||
// blue LED on ESP-12F
|
||||
const int led = 2;
|
||||
const int hour = 10;
|
||||
const int minute = 0;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
|
||||
pinMode(led, OUTPUT);
|
||||
// led is off when pin is high
|
||||
digitalWrite(led, 1);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay (500);
|
||||
Serial.print (".");
|
||||
}
|
||||
|
||||
timeClient.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
timeClient.update();
|
||||
|
||||
Serial.println(timeClient.getFormattedTime());
|
||||
if(timeClient.isTimeSet()) {
|
||||
if (hour == timeClient.getHours() && minute == timeClient.getMinutes()) {
|
||||
digitalWrite(led, 0);
|
||||
}
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
24
lib/NTPClient-master/keywords.txt
Normal file
24
lib/NTPClient-master/keywords.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
NTPClient KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
end KEYWORD2
|
||||
update KEYWORD2
|
||||
forceUpdate KEYWORD2
|
||||
isTimeSet KEYWORD2
|
||||
getDay KEYWORD2
|
||||
getHours KEYWORD2
|
||||
getMinutes KEYWORD2
|
||||
getSeconds KEYWORD2
|
||||
getFormattedTime KEYWORD2
|
||||
getEpochTime KEYWORD2
|
||||
setTimeOffset KEYWORD2
|
||||
setUpdateInterval KEYWORD2
|
||||
setPoolServerName KEYWORD2
|
||||
9
lib/NTPClient-master/library.properties
Normal file
9
lib/NTPClient-master/library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=NTPClient
|
||||
version=3.2.1
|
||||
author=Fabrice Weinberg
|
||||
maintainer=Fabrice Weinberg <fabrice@weinberg.me>
|
||||
sentence=An NTPClient to connect to a time server
|
||||
paragraph=Get time from a NTP server and keep it in sync.
|
||||
category=Timing
|
||||
url=https://github.com/arduino-libraries/NTPClient
|
||||
architectures=*
|
||||
46
lib/README
Normal file
46
lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
15
platformio.ini
Normal file
15
platformio.ini
Normal file
@@ -0,0 +1,15 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
136
src/main.cpp
Normal file
136
src/main.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <MFRC522v2.h>
|
||||
#include <MFRC522DriverSPI.h>
|
||||
#include <MFRC522DriverPinSimple.h>
|
||||
#include <MFRC522Debug.h>
|
||||
#include <WiFi.h>
|
||||
#include <NTPClient.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
constexpr bool DEBUG = true;
|
||||
|
||||
// pins
|
||||
constexpr int redLedPin = 2;
|
||||
constexpr int greenLedPin = 4;
|
||||
constexpr int cardLedPin = 12;
|
||||
constexpr int buzzerPin = 13;
|
||||
|
||||
// wifi
|
||||
auto ssid = "ElaZereVsetko2g";
|
||||
auto password = "CoJeElaToJeEla";
|
||||
|
||||
// NTP client
|
||||
WiFiUDP ntpUDP;
|
||||
// Europe/Prague timezone and update every 60 seconds
|
||||
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000);
|
||||
|
||||
// vykradnuty kod netusim co to robi ale robi to
|
||||
MFRC522DriverPinSimple ss_pin(5); // Create digital pin driver
|
||||
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
|
||||
MFRC522 mfrc522{driver}; // Create MFRC522 instance
|
||||
|
||||
void debugPrint(String const& msg, const bool newLine = true) {
|
||||
if (DEBUG) {
|
||||
if (newLine) {
|
||||
Serial.println(msg);
|
||||
} else {
|
||||
Serial.print(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// cakaj na serial port
|
||||
while (!Serial) {
|
||||
delay(10);
|
||||
}
|
||||
|
||||
// init pins
|
||||
pinMode(redLedPin, OUTPUT);
|
||||
pinMode(greenLedPin, OUTPUT);
|
||||
pinMode(cardLedPin, OUTPUT);
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
|
||||
// pripoj sa na wifi
|
||||
debugPrint("Connecting to WiFi...");
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(1000);
|
||||
debugPrint(".", false);
|
||||
}
|
||||
if (DEBUG) {
|
||||
debugPrint(" connected!");
|
||||
}
|
||||
|
||||
// Turn off the red LED and turn on the green LED
|
||||
digitalWrite(redLedPin, LOW);
|
||||
digitalWrite(greenLedPin, HIGH);
|
||||
|
||||
// Initialize NTP client
|
||||
timeClient.begin();
|
||||
timeClient.update();
|
||||
|
||||
// Print the current time
|
||||
debugPrint("Current time: " + timeClient.getFormattedTime());
|
||||
|
||||
mfrc522.PCD_Init();
|
||||
|
||||
debugPrint("Cakam na kartu...");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
|
||||
if (!mfrc522.PICC_IsNewCardPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Select one of the cards.
|
||||
if (!mfrc522.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the current time in Unix time with microseconds
|
||||
timeClient.update();
|
||||
const unsigned long currentTime = timeClient.getEpochTime();
|
||||
const unsigned long microseconds = micros() % 1000000;
|
||||
|
||||
// Format the time with microseconds
|
||||
char timeWithMicroseconds[30];
|
||||
snprintf(timeWithMicroseconds, sizeof(timeWithMicroseconds), "%lu.%06lu", currentTime, microseconds);
|
||||
|
||||
// Format the UID
|
||||
String uidString = "";
|
||||
for (byte i = 0; i < mfrc522.uid.size; i++) {
|
||||
uidString += String(mfrc522.uid.uidByte[i], HEX);
|
||||
}
|
||||
|
||||
debugPrint("send: " + uidString);
|
||||
// Create the URL
|
||||
String url = "http://192.168.50.87:8111/api/timer/write/12345/" + uidString + "/" + String(timeWithMicroseconds) + "/";
|
||||
debugPrint("to: " + url);
|
||||
// Send the HTTP GET request
|
||||
HTTPClient http;
|
||||
http.begin(url);
|
||||
int httpResponseCode = http.GET();
|
||||
if (httpResponseCode > 0) {
|
||||
debugPrint("HTTP Response code: " + String(httpResponseCode));
|
||||
} else {
|
||||
debugPrint("Error on HTTP request");
|
||||
}
|
||||
http.end();
|
||||
|
||||
// Turn on the card LED and buzzer
|
||||
digitalWrite(cardLedPin, HIGH);
|
||||
tone(buzzerPin, 2000); // Generate 2000Hz tone
|
||||
delay(500); // Beep and light for 500 milliseconds
|
||||
digitalWrite(cardLedPin, LOW);
|
||||
noTone(buzzerPin); // Stop the tone
|
||||
|
||||
|
||||
delay(2000);
|
||||
|
||||
}
|
||||
11
test/README
Normal file
11
test/README
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Reference in New Issue
Block a user