├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── Kconfig
├── LICENSE
├── Makefile
├── PCB
├── Makefile
├── Round
│ ├── .gitignore
│ ├── README.md
│ ├── Round-90.png
│ ├── Round-bottom.png
│ ├── Round-panel-bottom.png
│ ├── Round-panel.png
│ ├── Round.kicad_pcb
│ ├── Round.kicad_prl
│ ├── Round.kicad_pro
│ ├── Round.kicad_sch
│ ├── Round.png
│ ├── Round.scad
│ ├── Round.stl
│ └── production
│ │ ├── bom.csv
│ │ ├── designators.csv
│ │ ├── gerber.zip
│ │ ├── netlist.ipc
│ │ └── positions.csv
└── Square
│ ├── .gitignore
│ ├── Cable.stl
│ ├── README.md
│ ├── Square-90.png
│ ├── Square-bottom.png
│ ├── Square.kicad_pcb
│ ├── Square.kicad_prl
│ ├── Square.kicad_pro
│ ├── Square.kicad_sch
│ ├── Square.png
│ ├── Square.scad
│ ├── Thick.stl
│ ├── Wall.stl
│ └── production
│ ├── bom.csv
│ ├── designators.csv
│ ├── gerber.zip
│ ├── netlist.ipc
│ └── positions.csv
├── PN532.pages
├── README.md
├── component.mk
├── idf_component.yml
├── include
└── pn532.h
├── makeloop.c
├── pn532.c
└── tools
├── .gitignore
├── Makefile
└── pn532test.c
/.gitignore:
--------------------------------------------------------------------------------
1 | makeloop
2 | makeloop.c.BAK
3 | makeloop.dSYM
4 | *.o
5 | *~
6 | *.swp
7 | .DS_Store
8 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "PCB/PCBCase"]
2 | path = PCB/PCBCase
3 | url = https://github.com/revk/PCBCase
4 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | idf_component_register(
2 | SRCS "pn532.c"
3 | INCLUDE_DIRS "include"
4 | REQUIRES "driver"
5 | )
6 |
--------------------------------------------------------------------------------
/Kconfig:
--------------------------------------------------------------------------------
1 | menu "PN532"
2 |
3 | config PN532_DEBUG_DX
4 | bool "Debug DX"
5 | default n
6 | help
7 | Debug DESFire messages and errors
8 |
9 | config PN532_DEBUG_MSG
10 | bool "Debug MSG"
11 | default n
12 | help
13 | Debug message level
14 |
15 | config PN532_DUMP
16 | bool "Dump Serial"
17 | default n
18 | help
19 | Dump all serial data to/from PN532
20 |
21 | endmenu
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | makeloop: makeloop.c
2 | gcc -I/usr/local/include -L/usr/local/lib -O -o $@ $< -lpopt -lm -g
3 |
4 | clean:
5 | idf.py clean
6 |
7 | pull:
8 | git pull
9 | git submodule update --recursive
10 |
11 | update:
12 | -git pull
13 | -git commit -a
14 | git submodule update --init --recursive --remote
15 | idf.py update-dependencies
16 | -git commit -a -m "Library update"
17 |
18 | KiCad/PN532-wall.stl: KiCad/PN532.scad Makefile
19 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=0 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true
20 |
21 | KiCad/PN532-cable.stl: KiCad/PN532.scad Makefile
22 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=1 -Dthick=3 -Draspox=true -Dspox=false -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=false
23 |
24 | KiCad/PN532-thick.stl: KiCad/PN532.scad Makefile
25 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=10 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true
26 |
27 | PCBCase/case: PCBCase/case.c
28 | make -C PCBCase
29 |
30 | %.stl: %.scad
31 | echo "Making $@"
32 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@
33 | echo "Made $@"
34 |
35 | stl: PCB/Round/Round.stl PCB/Square/Wall.stl PCB/Square/Cable.stl PCB/Square/Thick.stl
36 |
37 | PCB/Round/Round.scad: PCB/Round/Round.kicad_pcb PCBCase/case Makefile
38 | PCBCase/case -n -o $@ $< --base=0.8 --top=2.5 --ignore=J1,J2 --pcb=2
39 | @echo "base();" >> $@
40 | @echo "translate([spacing,0,0])difference(){top();translate([casewall+pcbwidth/2-13/2,casewall+pcblength/2+6.5-5/2,-1])cube([15.5,5,10]);}" >> $@
41 |
42 | PCB/Square/Wall.stl: PCB/Square/Square.scad Makefile
43 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=0 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true
44 |
45 | PCB/Square/Cable.stl: PCB/Square/Square.scad Makefile
46 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=1 -Dthick=3 -Draspox=true -Dspox=false -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=false
47 |
48 | PCB/Square/Thick.stl: PCB/Square/Square.scad Makefile
49 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@ -Dbase=10 -Dthick=3 -Draspox=false -Dspox=true -Dtamper=true -Dbell=false -Dmilligrid=false -Dscrews=true
50 |
51 |
--------------------------------------------------------------------------------
/PCB/Makefile:
--------------------------------------------------------------------------------
1 | all: png
2 |
3 | png: $(patsubst %.kicad_pcb,%.png,$(wildcard */*.kicad_pcb))
4 |
5 | PCBCase/case: PCBCase/case.c
6 | make -C PCBCase
7 |
8 | PCBCase/clean: PCBCase/clean.c
9 | make -C PCBCase
10 |
11 | %.stl: %.scad
12 | echo "Making $@"
13 | /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $< -o $@
14 | echo "Made $@"
15 |
16 | %.png: %.kicad_pcb PCBCase/clean PCBCase/render Makefile
17 | PCBCase/render $<
18 |
--------------------------------------------------------------------------------
/PCB/Round/.gitignore:
--------------------------------------------------------------------------------
1 | *-backups
2 | *cache*
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/PCB/Round/README.md:
--------------------------------------------------------------------------------
1 | # Round
2 |
3 | These files are for use in [KiCad](https://www.kicad.org).
4 |
5 | ## Trademark
6 |
7 | This is an open source project, but bear in mind you cannot sell boards bearing the Andrews & Arnold Ltd name, the A&A logo, the registered trademark AJK logo, or the GS1 allocated EANs assigned to Andrews & Arnold Ltd.
8 |
9 | ## Images
10 |
11 | 

12 | 
13 |
14 | *Auto generated 2025-01-19T12:50:51*
15 |
--------------------------------------------------------------------------------
/PCB/Round/Round-90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-90.png
--------------------------------------------------------------------------------
/PCB/Round/Round-bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-bottom.png
--------------------------------------------------------------------------------
/PCB/Round/Round-panel-bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-panel-bottom.png
--------------------------------------------------------------------------------
/PCB/Round/Round-panel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round-panel.png
--------------------------------------------------------------------------------
/PCB/Round/Round.kicad_prl:
--------------------------------------------------------------------------------
1 | {
2 | "board": {
3 | "active_layer": 0,
4 | "active_layer_preset": "",
5 | "auto_track_width": true,
6 | "hidden_netclasses": [],
7 | "hidden_nets": [],
8 | "high_contrast_mode": 1,
9 | "net_color_mode": 1,
10 | "opacity": {
11 | "images": 0.6,
12 | "pads": 1.0,
13 | "shapes": 1.0,
14 | "tracks": 1.0,
15 | "vias": 1.0,
16 | "zones": 0.6
17 | },
18 | "ratsnest_display_mode": 0,
19 | "selection_filter": {
20 | "dimensions": true,
21 | "footprints": true,
22 | "graphics": true,
23 | "keepouts": true,
24 | "lockedItems": true,
25 | "otherItems": true,
26 | "pads": true,
27 | "text": true,
28 | "tracks": true,
29 | "vias": true,
30 | "zones": true
31 | },
32 | "visible_items": [
33 | 0,
34 | 1,
35 | 2,
36 | 3,
37 | 4,
38 | 5,
39 | 8,
40 | 9,
41 | 10,
42 | 11,
43 | 12,
44 | 13,
45 | 14,
46 | 15,
47 | 16,
48 | 17,
49 | 18,
50 | 19,
51 | 20,
52 | 21,
53 | 22,
54 | 23,
55 | 24,
56 | 25,
57 | 26,
58 | 27,
59 | 28,
60 | 29,
61 | 30,
62 | 32,
63 | 33,
64 | 34,
65 | 35,
66 | 36,
67 | 41
68 | ],
69 | "visible_layers": "0fffffff_ffffffff",
70 | "zone_display_mode": 0
71 | },
72 | "git": {
73 | "repo_password": "",
74 | "repo_type": "",
75 | "repo_username": "",
76 | "ssh_key": ""
77 | },
78 | "meta": {
79 | "filename": "Round.kicad_prl",
80 | "version": 4
81 | },
82 | "net_inspector_panel": {
83 | "col_hidden": [
84 | false,
85 | false,
86 | false,
87 | false,
88 | false,
89 | false,
90 | false,
91 | false,
92 | false,
93 | false
94 | ],
95 | "col_order": [
96 | 0,
97 | 1,
98 | 2,
99 | 3,
100 | 4,
101 | 5,
102 | 6,
103 | 7,
104 | 8,
105 | 9
106 | ],
107 | "col_widths": [
108 | 156,
109 | 141,
110 | 103,
111 | 71,
112 | 103,
113 | 103,
114 | 103,
115 | 74,
116 | 103,
117 | 103
118 | ],
119 | "custom_group_rules": [],
120 | "expanded_rows": [],
121 | "filter_by_net_name": true,
122 | "filter_by_netclass": true,
123 | "filter_text": "",
124 | "group_by_constraint": false,
125 | "group_by_netclass": false,
126 | "show_unconnected_nets": false,
127 | "show_zero_pad_nets": false,
128 | "sort_ascending": true,
129 | "sorting_column": 0
130 | },
131 | "project": {
132 | "files": []
133 | },
134 | "schematic": {
135 | "selection_filter": {
136 | "graphics": true,
137 | "images": true,
138 | "labels": true,
139 | "lockedItems": false,
140 | "otherItems": true,
141 | "pins": true,
142 | "symbols": true,
143 | "text": true,
144 | "wires": true
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/PCB/Round/Round.kicad_pro:
--------------------------------------------------------------------------------
1 | {
2 | "board": {
3 | "3dviewports": [],
4 | "design_settings": {
5 | "defaults": {
6 | "apply_defaults_to_fp_fields": false,
7 | "apply_defaults_to_fp_shapes": false,
8 | "apply_defaults_to_fp_text": false,
9 | "board_outline_line_width": 0.05,
10 | "copper_line_width": 0.2,
11 | "copper_text_italic": false,
12 | "copper_text_size_h": 1.5,
13 | "copper_text_size_v": 1.5,
14 | "copper_text_thickness": 0.3,
15 | "copper_text_upright": false,
16 | "courtyard_line_width": 0.05,
17 | "dimension_precision": 4,
18 | "dimension_units": 3,
19 | "dimensions": {
20 | "arrow_length": 1270000,
21 | "extension_offset": 500000,
22 | "keep_text_aligned": true,
23 | "suppress_zeroes": false,
24 | "text_position": 0,
25 | "units_format": 1
26 | },
27 | "fab_line_width": 0.1,
28 | "fab_text_italic": false,
29 | "fab_text_size_h": 1.0,
30 | "fab_text_size_v": 1.0,
31 | "fab_text_thickness": 0.15,
32 | "fab_text_upright": false,
33 | "other_line_width": 0.1,
34 | "other_text_italic": false,
35 | "other_text_size_h": 1.0,
36 | "other_text_size_v": 1.0,
37 | "other_text_thickness": 0.15,
38 | "other_text_upright": false,
39 | "pads": {
40 | "drill": 1.8,
41 | "height": 1.8,
42 | "width": 1.8
43 | },
44 | "silk_line_width": 0.12,
45 | "silk_text_italic": false,
46 | "silk_text_size_h": 1.0,
47 | "silk_text_size_v": 1.0,
48 | "silk_text_thickness": 0.15,
49 | "silk_text_upright": false,
50 | "zones": {
51 | "45_degree_only": false,
52 | "min_clearance": 0.25
53 | }
54 | },
55 | "diff_pair_dimensions": [
56 | {
57 | "gap": 0.0,
58 | "via_gap": 0.0,
59 | "width": 0.0
60 | }
61 | ],
62 | "drc_exclusions": [],
63 | "meta": {
64 | "filename": "board_design_settings.json",
65 | "version": 2
66 | },
67 | "rule_severities": {
68 | "annular_width": "error",
69 | "clearance": "error",
70 | "connection_width": "warning",
71 | "copper_edge_clearance": "warning",
72 | "copper_sliver": "warning",
73 | "courtyards_overlap": "error",
74 | "creepage": "error",
75 | "diff_pair_gap_out_of_range": "error",
76 | "diff_pair_uncoupled_length_too_long": "error",
77 | "drill_out_of_range": "error",
78 | "duplicate_footprints": "warning",
79 | "extra_footprint": "warning",
80 | "footprint": "error",
81 | "footprint_filters_mismatch": "ignore",
82 | "footprint_symbol_mismatch": "warning",
83 | "footprint_type_mismatch": "error",
84 | "hole_clearance": "error",
85 | "hole_near_hole": "error",
86 | "hole_to_hole": "warning",
87 | "holes_co_located": "warning",
88 | "invalid_outline": "error",
89 | "isolated_copper": "warning",
90 | "item_on_disabled_layer": "error",
91 | "items_not_allowed": "error",
92 | "length_out_of_range": "error",
93 | "lib_footprint_issues": "warning",
94 | "lib_footprint_mismatch": "warning",
95 | "malformed_courtyard": "error",
96 | "microvia_drill_out_of_range": "error",
97 | "mirrored_text_on_front_layer": "warning",
98 | "missing_courtyard": "ignore",
99 | "missing_footprint": "warning",
100 | "net_conflict": "warning",
101 | "nonmirrored_text_on_back_layer": "warning",
102 | "npth_inside_courtyard": "ignore",
103 | "padstack": "error",
104 | "pth_inside_courtyard": "ignore",
105 | "shorting_items": "error",
106 | "silk_edge_clearance": "warning",
107 | "silk_over_copper": "ignore",
108 | "silk_overlap": "warning",
109 | "skew_out_of_range": "error",
110 | "solder_mask_bridge": "error",
111 | "starved_thermal": "error",
112 | "text_height": "warning",
113 | "text_thickness": "warning",
114 | "through_hole_pad_without_hole": "error",
115 | "too_many_vias": "error",
116 | "track_angle": "error",
117 | "track_dangling": "warning",
118 | "track_segment_length": "error",
119 | "track_width": "error",
120 | "tracks_crossing": "error",
121 | "unconnected_items": "error",
122 | "unresolved_variable": "error",
123 | "via_dangling": "warning",
124 | "zones_intersect": "error"
125 | },
126 | "rule_severitieslegacy_courtyards_overlap": true,
127 | "rule_severitieslegacy_no_courtyard_defined": false,
128 | "rules": {
129 | "allow_blind_buried_vias": false,
130 | "allow_microvias": false,
131 | "max_error": 0.005,
132 | "min_clearance": 0.125,
133 | "min_connection": 0.0,
134 | "min_copper_edge_clearance": 0.1,
135 | "min_groove_width": 0.0,
136 | "min_hole_clearance": 0.1,
137 | "min_hole_to_hole": 0.2,
138 | "min_microvia_diameter": 0.3,
139 | "min_microvia_drill": 0.2,
140 | "min_resolved_spokes": 1,
141 | "min_silk_clearance": 0.0,
142 | "min_text_height": 0.5,
143 | "min_text_thickness": 0.08,
144 | "min_through_hole_diameter": 0.2,
145 | "min_track_width": 0.125,
146 | "min_via_annular_width": 0.05,
147 | "min_via_diameter": 0.4,
148 | "solder_mask_to_copper_clearance": 0.005,
149 | "use_height_for_length_calcs": true
150 | },
151 | "teardrop_options": [
152 | {
153 | "td_onpthpad": true,
154 | "td_onroundshapesonly": false,
155 | "td_onsmdpad": true,
156 | "td_ontrackend": true,
157 | "td_onvia": true
158 | }
159 | ],
160 | "teardrop_parameters": [
161 | {
162 | "td_allow_use_two_tracks": true,
163 | "td_curve_segcount": 5,
164 | "td_height_ratio": 1.0,
165 | "td_length_ratio": 0.5,
166 | "td_maxheight": 2.0,
167 | "td_maxlen": 1.0,
168 | "td_on_pad_in_zone": true,
169 | "td_target_name": "td_round_shape",
170 | "td_width_to_size_filter_ratio": 0.9
171 | },
172 | {
173 | "td_allow_use_two_tracks": true,
174 | "td_curve_segcount": 5,
175 | "td_height_ratio": 1.0,
176 | "td_length_ratio": 0.5,
177 | "td_maxheight": 2.0,
178 | "td_maxlen": 1.0,
179 | "td_on_pad_in_zone": true,
180 | "td_target_name": "td_rect_shape",
181 | "td_width_to_size_filter_ratio": 0.9
182 | },
183 | {
184 | "td_allow_use_two_tracks": true,
185 | "td_curve_segcount": 5,
186 | "td_height_ratio": 1.0,
187 | "td_length_ratio": 0.5,
188 | "td_maxheight": 2.0,
189 | "td_maxlen": 1.0,
190 | "td_on_pad_in_zone": true,
191 | "td_target_name": "td_track_end",
192 | "td_width_to_size_filter_ratio": 0.9
193 | }
194 | ],
195 | "track_widths": [
196 | 0.0,
197 | 0.125,
198 | 0.2,
199 | 0.25,
200 | 0.3,
201 | 0.5
202 | ],
203 | "tuning_pattern_settings": {
204 | "diff_pair_defaults": {
205 | "corner_radius_percentage": 80,
206 | "corner_style": 1,
207 | "max_amplitude": 1.0,
208 | "min_amplitude": 0.2,
209 | "single_sided": false,
210 | "spacing": 1.0
211 | },
212 | "diff_pair_skew_defaults": {
213 | "corner_radius_percentage": 80,
214 | "corner_style": 1,
215 | "max_amplitude": 1.0,
216 | "min_amplitude": 0.2,
217 | "single_sided": false,
218 | "spacing": 0.6
219 | },
220 | "single_track_defaults": {
221 | "corner_radius_percentage": 80,
222 | "corner_style": 1,
223 | "max_amplitude": 1.0,
224 | "min_amplitude": 0.2,
225 | "single_sided": false,
226 | "spacing": 0.6
227 | }
228 | },
229 | "via_dimensions": [
230 | {
231 | "diameter": 0.0,
232 | "drill": 0.0
233 | }
234 | ],
235 | "zones_allow_external_fillets": false,
236 | "zones_use_no_outline": true
237 | },
238 | "ipc2581": {
239 | "dist": "",
240 | "distpn": "",
241 | "internal_id": "",
242 | "mfg": "",
243 | "mpn": ""
244 | },
245 | "layer_pairs": [],
246 | "layer_presets": [],
247 | "viewports": []
248 | },
249 | "boards": [],
250 | "cvpcb": {
251 | "equivalence_files": []
252 | },
253 | "erc": {
254 | "erc_exclusions": [],
255 | "meta": {
256 | "version": 0
257 | },
258 | "pin_map": [
259 | [
260 | 0,
261 | 0,
262 | 0,
263 | 0,
264 | 0,
265 | 0,
266 | 1,
267 | 0,
268 | 0,
269 | 0,
270 | 0,
271 | 2
272 | ],
273 | [
274 | 0,
275 | 2,
276 | 0,
277 | 1,
278 | 0,
279 | 0,
280 | 1,
281 | 0,
282 | 2,
283 | 2,
284 | 2,
285 | 2
286 | ],
287 | [
288 | 0,
289 | 0,
290 | 0,
291 | 0,
292 | 0,
293 | 0,
294 | 1,
295 | 0,
296 | 1,
297 | 0,
298 | 1,
299 | 2
300 | ],
301 | [
302 | 0,
303 | 1,
304 | 0,
305 | 0,
306 | 0,
307 | 0,
308 | 1,
309 | 1,
310 | 2,
311 | 1,
312 | 1,
313 | 2
314 | ],
315 | [
316 | 0,
317 | 0,
318 | 0,
319 | 0,
320 | 0,
321 | 0,
322 | 1,
323 | 0,
324 | 0,
325 | 0,
326 | 0,
327 | 2
328 | ],
329 | [
330 | 0,
331 | 0,
332 | 0,
333 | 0,
334 | 0,
335 | 0,
336 | 0,
337 | 0,
338 | 0,
339 | 0,
340 | 0,
341 | 2
342 | ],
343 | [
344 | 1,
345 | 1,
346 | 1,
347 | 1,
348 | 1,
349 | 0,
350 | 1,
351 | 1,
352 | 1,
353 | 1,
354 | 1,
355 | 2
356 | ],
357 | [
358 | 0,
359 | 0,
360 | 0,
361 | 1,
362 | 0,
363 | 0,
364 | 1,
365 | 0,
366 | 0,
367 | 0,
368 | 0,
369 | 2
370 | ],
371 | [
372 | 0,
373 | 2,
374 | 1,
375 | 2,
376 | 0,
377 | 0,
378 | 1,
379 | 0,
380 | 2,
381 | 2,
382 | 2,
383 | 2
384 | ],
385 | [
386 | 0,
387 | 2,
388 | 0,
389 | 1,
390 | 0,
391 | 0,
392 | 1,
393 | 0,
394 | 2,
395 | 0,
396 | 0,
397 | 2
398 | ],
399 | [
400 | 0,
401 | 2,
402 | 1,
403 | 1,
404 | 0,
405 | 0,
406 | 1,
407 | 0,
408 | 2,
409 | 0,
410 | 0,
411 | 2
412 | ],
413 | [
414 | 2,
415 | 2,
416 | 2,
417 | 2,
418 | 2,
419 | 2,
420 | 2,
421 | 2,
422 | 2,
423 | 2,
424 | 2,
425 | 2
426 | ]
427 | ],
428 | "rule_severities": {
429 | "bus_definition_conflict": "error",
430 | "bus_entry_needed": "error",
431 | "bus_to_bus_conflict": "error",
432 | "bus_to_net_conflict": "error",
433 | "conflicting_netclasses": "error",
434 | "different_unit_footprint": "error",
435 | "different_unit_net": "error",
436 | "duplicate_reference": "error",
437 | "duplicate_sheet_names": "error",
438 | "endpoint_off_grid": "warning",
439 | "extra_units": "error",
440 | "footprint_filter": "ignore",
441 | "footprint_link_issues": "warning",
442 | "four_way_junction": "ignore",
443 | "global_label_dangling": "warning",
444 | "hier_label_mismatch": "error",
445 | "label_dangling": "error",
446 | "label_multiple_wires": "warning",
447 | "lib_symbol_issues": "warning",
448 | "lib_symbol_mismatch": "warning",
449 | "missing_bidi_pin": "warning",
450 | "missing_input_pin": "warning",
451 | "missing_power_pin": "error",
452 | "missing_unit": "warning",
453 | "multiple_net_names": "warning",
454 | "net_not_bus_member": "warning",
455 | "no_connect_connected": "warning",
456 | "no_connect_dangling": "warning",
457 | "pin_not_connected": "error",
458 | "pin_not_driven": "error",
459 | "pin_to_pin": "warning",
460 | "power_pin_not_driven": "error",
461 | "same_local_global_label": "warning",
462 | "similar_label_and_power": "warning",
463 | "similar_labels": "warning",
464 | "similar_power": "warning",
465 | "simulation_model_issue": "ignore",
466 | "single_global_label": "ignore",
467 | "unannotated": "error",
468 | "unconnected_wire_endpoint": "warning",
469 | "unit_value_mismatch": "error",
470 | "unresolved_variable": "error",
471 | "wire_dangling": "error"
472 | }
473 | },
474 | "libraries": {
475 | "pinned_footprint_libs": [],
476 | "pinned_symbol_libs": []
477 | },
478 | "meta": {
479 | "filename": "Round.kicad_pro",
480 | "version": 2
481 | },
482 | "net_settings": {
483 | "classes": [
484 | {
485 | "bus_width": 12,
486 | "clearance": 0.125,
487 | "diff_pair_gap": 0.25,
488 | "diff_pair_via_gap": 0.25,
489 | "diff_pair_width": 0.2,
490 | "line_style": 0,
491 | "microvia_diameter": 0.3,
492 | "microvia_drill": 0.1,
493 | "name": "Default",
494 | "pcb_color": "rgba(0, 0, 0, 0.000)",
495 | "priority": 2147483647,
496 | "schematic_color": "rgba(0, 0, 0, 0.000)",
497 | "track_width": 0.125,
498 | "via_diameter": 0.8,
499 | "via_drill": 0.4,
500 | "wire_width": 6
501 | },
502 | {
503 | "bus_width": 12,
504 | "clearance": 0.125,
505 | "diff_pair_gap": 0.25,
506 | "diff_pair_via_gap": 0.25,
507 | "diff_pair_width": 0.2,
508 | "line_style": 0,
509 | "microvia_diameter": 0.3,
510 | "microvia_drill": 0.1,
511 | "name": "Power",
512 | "pcb_color": "rgba(0, 0, 0, 0.000)",
513 | "priority": 0,
514 | "schematic_color": "rgba(0, 0, 0, 0.000)",
515 | "track_width": 0.25,
516 | "via_diameter": 0.8,
517 | "via_drill": 0.4,
518 | "wire_width": 6
519 | }
520 | ],
521 | "meta": {
522 | "version": 4
523 | },
524 | "net_colors": null,
525 | "netclass_assignments": null,
526 | "netclass_patterns": [
527 | {
528 | "netclass": "Power",
529 | "pattern": "GND"
530 | },
531 | {
532 | "netclass": "Power",
533 | "pattern": "5V"
534 | }
535 | ]
536 | },
537 | "pcbnew": {
538 | "last_paths": {
539 | "gencad": "",
540 | "idf": "",
541 | "netlist": "",
542 | "plot": "",
543 | "pos_files": "",
544 | "specctra_dsn": "",
545 | "step": "",
546 | "svg": "",
547 | "vrml": ""
548 | },
549 | "page_layout_descr_file": ""
550 | },
551 | "schematic": {
552 | "annotate_start_num": 0,
553 | "bom_export_filename": "",
554 | "bom_fmt_presets": [],
555 | "bom_fmt_settings": {
556 | "field_delimiter": ",",
557 | "keep_line_breaks": false,
558 | "keep_tabs": false,
559 | "name": "CSV",
560 | "ref_delimiter": ",",
561 | "ref_range_delimiter": "",
562 | "string_delimiter": "\""
563 | },
564 | "bom_presets": [],
565 | "bom_settings": {
566 | "exclude_dnp": false,
567 | "fields_ordered": [
568 | {
569 | "group_by": false,
570 | "label": "Reference",
571 | "name": "Reference",
572 | "show": true
573 | },
574 | {
575 | "group_by": true,
576 | "label": "Value",
577 | "name": "Value",
578 | "show": true
579 | },
580 | {
581 | "group_by": false,
582 | "label": "Datasheet",
583 | "name": "Datasheet",
584 | "show": true
585 | },
586 | {
587 | "group_by": false,
588 | "label": "Footprint",
589 | "name": "Footprint",
590 | "show": true
591 | },
592 | {
593 | "group_by": false,
594 | "label": "Qty",
595 | "name": "${QUANTITY}",
596 | "show": true
597 | },
598 | {
599 | "group_by": true,
600 | "label": "DNP",
601 | "name": "${DNP}",
602 | "show": true
603 | }
604 | ],
605 | "filter_string": "",
606 | "group_symbols": true,
607 | "include_excluded_from_bom": false,
608 | "name": "Grouped By Value",
609 | "sort_asc": true,
610 | "sort_field": "Reference"
611 | },
612 | "connection_grid_size": 50.0,
613 | "drawing": {
614 | "dashed_lines_dash_length_ratio": 12.0,
615 | "dashed_lines_gap_length_ratio": 3.0,
616 | "default_line_thickness": 6.0,
617 | "default_text_size": 50.0,
618 | "field_names": [],
619 | "intersheets_ref_own_page": false,
620 | "intersheets_ref_prefix": "",
621 | "intersheets_ref_short": false,
622 | "intersheets_ref_show": false,
623 | "intersheets_ref_suffix": "",
624 | "junction_size_choice": 3,
625 | "label_size_ratio": 0.25,
626 | "operating_point_overlay_i_precision": 3,
627 | "operating_point_overlay_i_range": "~A",
628 | "operating_point_overlay_v_precision": 3,
629 | "operating_point_overlay_v_range": "~V",
630 | "overbar_offset_ratio": 1.23,
631 | "pin_symbol_size": 25.0,
632 | "text_offset_ratio": 0.08
633 | },
634 | "legacy_lib_dir": "",
635 | "legacy_lib_list": [],
636 | "meta": {
637 | "version": 1
638 | },
639 | "net_format_name": "",
640 | "ngspice": {
641 | "fix_include_paths": true,
642 | "fix_passive_vals": false,
643 | "meta": {
644 | "version": 0
645 | },
646 | "model_mode": 0,
647 | "workbook_filename": ""
648 | },
649 | "page_layout_descr_file": "",
650 | "plot_directory": "",
651 | "space_save_all_events": true,
652 | "spice_adjust_passive_values": false,
653 | "spice_current_sheet_as_root": false,
654 | "spice_external_command": "spice \"%I\"",
655 | "spice_model_current_sheet_as_root": true,
656 | "spice_save_all_currents": false,
657 | "spice_save_all_dissipations": false,
658 | "spice_save_all_voltages": false,
659 | "subpart_first_id": 65,
660 | "subpart_id_separator": 0
661 | },
662 | "sheets": [
663 | [
664 | "0217dfc4-fc13-4699-99ad-d9948522648e",
665 | "Root"
666 | ]
667 | ],
668 | "text_variables": {
669 | "DATE": "2023-03-22"
670 | }
671 | }
672 |
--------------------------------------------------------------------------------
/PCB/Round/Round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/Round.png
--------------------------------------------------------------------------------
/PCB/Round/Round.scad:
--------------------------------------------------------------------------------
1 | // Generated case design for PCB/Round/Round.kicad_pcb
2 | // By https://github.com/revk/PCBCase
3 | // Generated 2023-07-01 11:21:10
4 | // title: PN532 NFC reader (HSU)
5 | // date: ${DATE}
6 | // rev: 7
7 | // company: Adrian Kennard Andrews & Arnold Ltd
8 | // comment: www.m.euk
9 | //
10 |
11 | // Globals
12 | margin=0.500000;
13 | overlap=2.000000;
14 | lip=0.000000;
15 | casebase=0.800000;
16 | casetop=2.500000;
17 | casewall=3.000000;
18 | fit=0.000000;
19 | edge=1.000000;
20 | pcbthickness=0.800000;
21 | nohull=false;
22 | hullcap=1.000000;
23 | hulledge=1.000000;
24 | useredge=false;
25 |
26 | module outline(h=pcbthickness,r=0){linear_extrude(height=h)offset(r=r)polygon(points=[[46.000000,23.000000],[45.961088,21.662669],[45.844482,20.329863],[45.650578,19.006092],[45.380032,17.695835],[45.033759,16.403526],[44.612930,15.133537],[44.118970,13.890165],[43.553551,12.677619],[42.918584,11.500000],[42.216220,10.361294],[41.448833,9.265352],[40.619022,8.215885],[39.729594,7.216442],[38.783558,6.270406],[37.784115,5.380978],[36.734648,4.551167],[35.638706,3.783780],[34.500000,3.081416],[33.322381,2.446449],[32.109835,1.881030],[30.866463,1.387070],[29.596474,0.966241],[28.304165,0.619968],[26.993908,0.349422],[25.670137,0.155518],[24.337331,0.038912],[23.000000,0.000000],[21.662669,0.038912],[20.329863,0.155518],[19.006092,0.349422],[17.695835,0.619968],[16.403526,0.966241],[15.133537,1.387070],[13.890165,1.881030],[12.677619,2.446449],[11.500000,3.081416],[10.361294,3.783780],[9.265352,4.551167],[8.215885,5.380978],[7.216442,6.270406],[6.270406,7.216442],[5.380978,8.215885],[4.551167,9.265352],[3.783780,10.361294],[3.081416,11.500000],[2.446449,12.677619],[1.881030,13.890165],[1.387070,15.133537],[0.966241,16.403526],[0.619968,17.695835],[0.349422,19.006092],[0.155518,20.329863],[0.038912,21.662669],[0.000000,23.000000],[0.038912,24.337331],[0.155518,25.670137],[0.349422,26.993908],[0.619968,28.304165],[0.966241,29.596474],[1.387070,30.866463],[1.881030,32.109835],[2.446449,33.322381],[3.081416,34.500000],[3.783780,35.638706],[4.551167,36.734648],[5.380978,37.784115],[6.270406,38.783558],[7.216442,39.729594],[8.215885,40.619022],[9.265352,41.448833],[10.361294,42.216220],[11.500000,42.918584],[12.677619,43.553551],[13.890165,44.118970],[15.133537,44.612930],[16.403526,45.033759],[17.695835,45.380032],[19.006092,45.650578],[20.329863,45.844482],[21.662669,45.961088],[23.000000,46.000000],[24.337331,45.961088],[25.670137,45.844482],[26.993908,45.650578],[28.304165,45.380032],[29.596474,45.033759],[30.866463,44.612930],[32.109835,44.118970],[33.322381,43.553551],[34.500000,42.918584],[35.638706,42.216220],[36.734648,41.448833],[37.784115,40.619022],[38.783558,39.729594],[39.729594,38.783558],[40.619022,37.784115],[41.448833,36.734648],[42.216220,35.638706],[42.918584,34.500000],[43.553551,33.322381],[44.118970,32.109835],[44.612930,30.866463],[45.033759,29.596474],[45.380032,28.304165],[45.650578,26.993908],[45.844482,25.670137],[45.961088,24.337331]],paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107]]);}
27 |
28 | module pcb(h=pcbthickness,r=0){linear_extrude(height=h)offset(r=r)polygon(points=[[46.000000,23.000000],[45.961088,21.662669],[45.844482,20.329863],[45.650578,19.006092],[45.380032,17.695835],[45.033759,16.403526],[44.612930,15.133537],[44.118970,13.890165],[43.553551,12.677619],[42.918584,11.500000],[42.216220,10.361294],[41.448833,9.265352],[40.619022,8.215885],[39.729594,7.216442],[38.783558,6.270406],[37.784115,5.380978],[36.734648,4.551167],[35.638706,3.783780],[34.500000,3.081416],[33.322381,2.446449],[32.109835,1.881030],[30.866463,1.387070],[29.596474,0.966241],[28.304165,0.619968],[26.993908,0.349422],[25.670137,0.155518],[24.337331,0.038912],[23.000000,0.000000],[21.662669,0.038912],[20.329863,0.155518],[19.006092,0.349422],[17.695835,0.619968],[16.403526,0.966241],[15.133537,1.387070],[13.890165,1.881030],[12.677619,2.446449],[11.500000,3.081416],[10.361294,3.783780],[9.265352,4.551167],[8.215885,5.380978],[7.216442,6.270406],[6.270406,7.216442],[5.380978,8.215885],[4.551167,9.265352],[3.783780,10.361294],[3.081416,11.500000],[2.446449,12.677619],[1.881030,13.890165],[1.387070,15.133537],[0.966241,16.403526],[0.619968,17.695835],[0.349422,19.006092],[0.155518,20.329863],[0.038912,21.662669],[0.000000,23.000000],[0.038912,24.337331],[0.155518,25.670137],[0.349422,26.993908],[0.619968,28.304165],[0.966241,29.596474],[1.387070,30.866463],[1.881030,32.109835],[2.446449,33.322381],[3.081416,34.500000],[3.783780,35.638706],[4.551167,36.734648],[5.380978,37.784115],[6.270406,38.783558],[7.216442,39.729594],[8.215885,40.619022],[9.265352,41.448833],[10.361294,42.216220],[11.500000,42.918584],[12.677619,43.553551],[13.890165,44.118970],[15.133537,44.612930],[16.403526,45.033759],[17.695835,45.380032],[19.006092,45.650578],[20.329863,45.844482],[21.662669,45.961088],[23.000000,46.000000],[24.337331,45.961088],[25.670137,45.844482],[26.993908,45.650578],[28.304165,45.380032],[29.596474,45.033759],[30.866463,44.612930],[32.109835,44.118970],[33.322381,43.553551],[34.500000,42.918584],[35.638706,42.216220],[36.734648,41.448833],[37.784115,40.619022],[38.783558,39.729594],[39.729594,38.783558],[40.619022,37.784115],[41.448833,36.734648],[42.216220,35.638706],[42.918584,34.500000],[43.553551,33.322381],[44.118970,32.109835],[44.612930,30.866463],[45.033759,29.596474],[45.380032,28.304165],[45.650578,26.993908],[45.844482,25.670137],[45.961088,24.337331]],paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107]]);}
29 | spacing=62.000000;
30 | pcbwidth=46.000000;
31 | pcblength=46.000000;
32 | // Populated PCB
33 | module board(pushed=false,hulled=false){
34 | translate([16.875000,26.440000,0.800000])rotate([0,0,90.000000])m2(pushed,hulled); // RevK:Crystal-3.2x2.5 Crystal_SMD_Abracon_ABM8G-4Pin_3.2x2.5mm (back)
35 | // Missing D2.1 LED_1206_3216Metric_Castellated
36 | // Missing D3.1 LED_1206_3216Metric_Castellated
37 | translate([12.800000,23.000000,0.800000])rotate([0,0,180.000000])translate([2.050000,0.000000,1.150000])rotate([-0.000000,-0.000000,-90.000000])m7(pushed,hulled); // RevK:ESE13 ESE13V01D (back)
38 | // Missing D1.1 LED_1206_3216Metric_Castellated
39 | translate([24.375000,31.240000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
40 | translate([26.800000,39.350000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
41 | translate([24.700000,38.600000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
42 | translate([32.000000,30.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
43 | translate([16.900000,38.600000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
44 | translate([29.150000,26.840000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
45 | translate([28.400000,29.140000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
46 | translate([16.875000,31.690000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
47 | translate([16.875000,28.940000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
48 | translate([32.000000,26.140000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
49 | translate([32.000000,24.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
50 | translate([22.300000,21.290000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
51 | translate([23.000000,26.440000,0.800000])rotate([0,0,-90.000000])m14(pushed,hulled); // RevK:QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm (back)
52 | translate([16.875000,23.940000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
53 | translate([21.625000,32.590000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
54 | translate([16.100000,33.590000,0.800000])rotate([0,0,-90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
55 | translate([32.000000,29.140000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
56 | translate([32.000000,27.640000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
57 | translate([20.700000,21.290000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
58 | translate([27.650000,26.840000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
59 | translate([16.100000,36.240000,0.800000])rotate([0,0,90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
60 | translate([24.270000,16.500000,0.800000])rotate([0,0,90.000000])m16(pushed,hulled,5); // RevK:PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left (back)
61 | translate([24.375000,32.590000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
62 | translate([24.700000,40.135000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
63 | translate([21.300000,38.600000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
64 | translate([28.600000,21.290000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
65 | translate([24.650000,20.540000,0.800000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
66 | translate([16.875000,30.340000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
67 | translate([24.650000,22.040000,0.800000])rotate([0,0,180.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
68 | translate([26.250000,35.440000,0.800000])rotate([0,0,45.000000])m18(pushed,hulled); // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric (back)
69 | translate([19.750000,35.440000,0.800000])rotate([0,0,-45.000000])m18(pushed,hulled); // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric (back)
70 | translate([19.200000,39.350000,0.800000])rotate([0,0,-90.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
71 | translate([27.000000,21.290000,0.800000])rotate([0,0,-90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
72 | translate([32.000000,32.540000,0.800000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back)
73 | translate([32.000000,18.240000,0.800000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
74 | translate([32.000000,22.740000,0.800000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back)
75 | translate([32.000000,20.140000,0.800000])rotate([0,0,180.000000])m19(pushed,hulled); // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6 (back)
76 | translate([21.300000,40.135000,0.800000])rotate([0,0,180.000000])m10(pushed,hulled); // RevK:C_0603 C_0603_1608Metric (back)
77 | translate([23.000000,44.410000,0.800000])rotate([0,0,90.000000])m25(pushed,hulled); // RevK:R_0805_ R_0805_2012Metric (back)
78 | translate([24.770000,42.510000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
79 | translate([21.230000,42.510000,0.800000])rotate([0,0,90.000000])m13(pushed,hulled); // RevK:R_0603 R_0603_1608Metric (back)
80 | translate([23.000000,23.000000,0.800000])translate([9.000000,14.000000,0.500000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,35.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back)
81 | translate([23.000000,23.000000,0.800000])translate([9.000000,-14.000000,0.500000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,-35.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back)
82 | translate([23.000000,23.000000,0.800000])translate([-12.000000,0.000000,1.300000])scale([0.580000,0.580000,0.580000])rotate([-0.000000,90.000000,-90.000000])m29(pushed,hulled); // RevK:PN532-Antenna6 653612 (back)
83 | }
84 |
85 | module b(cx,cy,z,w,l,h){translate([cx-w/2,cy-l/2,z])cube([w,l,h]);}
86 | module m2(pushed=false,hulled=false)
87 | { // RevK:Crystal-3.2x2.5 Crystal_SMD_Abracon_ABM8G-4Pin_3.2x2.5mm
88 | cube([3.2,2.5,1],center=true);
89 | }
90 |
91 | module m7(pushed=false,hulled=false)
92 | { // RevK:ESE13 ESE13V01D
93 | if(!hulled&&pushed) translate([0,2.05,-1.15])
94 | {
95 | b(0,0,0,3.6+0.4,4.2+0.4,1.2);
96 | b(0,-3.08,0,1.2+0.4,1.95+0.4,0.9);
97 | }
98 |
99 | }
100 |
101 | module m10(pushed=false,hulled=false)
102 | { // RevK:C_0603 C_0603_1608Metric
103 | b(0,0,0,1.6,0.95,0.2); // Pad size
104 | b(0,0,0,1.6,0.8,1); // Chip
105 | }
106 |
107 | module m13(pushed=false,hulled=false)
108 | { // RevK:R_0603 R_0603_1608Metric
109 | b(0,0,0,1.6,0.95,0.2); // Pad size
110 | b(0,0,0,1.6,0.8,0.5); // Chip
111 | }
112 |
113 | module m14(pushed=false,hulled=false)
114 | { // RevK:QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm
115 | cube([4.6,4.6,1],center=true);
116 | }
117 |
118 | module m16(pushed=false,hulled=false,n=0)
119 | { // RevK:PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left
120 | b(0,0,0,5.08,2.54*n,0.5);
121 | if(!hulled&&!pushed)
122 | {
123 | b(0,0,0,2.54,2.54*n,2.54);
124 | b(0,0,0,0.5,2.54*(n-1)+0.5,10);
125 | translate([0,0,4])b(0,0,0,5.08,n*2.54,100);
126 | }
127 | }
128 |
129 | module m18(pushed=false,hulled=false)
130 | { // Inductor_SMD:L_1008_2520Metric L_1008_2520Metric
131 | b(0,0,0,2.62,2.45,1.83); // Pad size
132 | }
133 |
134 | module m19(pushed=false,hulled=false)
135 | { // RevK:SOT-363_SC-70-6 SOT-363_SC-70-6
136 | b(0,0,0,1.15,2.0,1.1);
137 | b(0,0,0,2.1,2.0,0.6);
138 | }
139 |
140 | module m25(pushed=false,hulled=false)
141 | { // RevK:R_0805_ R_0805_2012Metric
142 | b(0,0,0,2,1.45,0.2); // Pad size
143 | b(0,0,0,2,1.2,0.5); // Chip
144 | }
145 |
146 | module m29(pushed=false,hulled=false)
147 | { // RevK:PN532-Antenna6 653612
148 | // Screw 6mm
149 | if(!hulled&&!pushed)
150 | rotate([0,-90,0],$fn=24)
151 | {
152 | hull()for(x=[-1,1])translate([x,0,-2])cylinder(d=12,h=2);
153 | hull()for(x=[-1,1])translate([x,0,0])cylinder(d1=12,d2=6,h=3);
154 | hull()for(x=[-1,1])translate([x,0,0])cylinder(d=6,h=100);
155 | }
156 |
157 | }
158 |
159 | height=casebase+pcbthickness+casetop;
160 | $fn=48;
161 |
162 | module boardh(pushed=false)
163 | { // Board with hulled parts
164 | union()
165 | {
166 | if(!nohull)intersection()
167 | {
168 | translate([0,0,hullcap-casebase])outline(casebase+pcbthickness+casetop-hullcap*2,-hulledge);
169 | hull()board(pushed,true);
170 | }
171 | board(pushed,false);
172 | pcb();
173 | }
174 | }
175 |
176 | module boardf()
177 | { // This is the board, but stretched up to make a push out in from the front
178 | render()
179 | {
180 | intersection()
181 | {
182 | translate([-casewall-1,-casewall-1,-casebase-1]) cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,height+2]);
183 | union()
184 | {
185 | minkowski()
186 | {
187 | boardh(true);
188 | cylinder(h=height+100,d=margin,$fn=8);
189 | }
190 | board(false,false);
191 | }
192 | }
193 | }
194 | }
195 |
196 | module boardb()
197 | { // This is the board, but stretched down to make a push out in from the back
198 | render()
199 | {
200 | intersection()
201 | {
202 | translate([-casewall-1,-casewall-1,-casebase-1]) cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,height+2]);
203 | union()
204 | {
205 | minkowski()
206 | {
207 | boardh(true);
208 | translate([0,0,-height-100])
209 | cylinder(h=height+100,d=margin,$fn=8);
210 | }
211 | board(false,false);
212 | }
213 | }
214 | }
215 | }
216 |
217 | module boardm()
218 | {
219 | render()
220 | {
221 | minkowski()
222 | {
223 | translate([0,0,-margin/2])cylinder(d=margin,h=margin,$fn=8);
224 | boardh(false);
225 | }
226 | //intersection()
227 | //{
228 | //translate([0,0,-(casebase-hullcap)])pcb(pcbthickness+(casebase-hullcap)+(casetop-hullcap));
229 | //translate([0,0,-(casebase-hullcap)])outline(pcbthickness+(casebase-hullcap)+(casetop-hullcap));
230 | boardh(false);
231 | //}
232 | }
233 | }
234 |
235 | module pcbh(h=pcbthickness,r=0)
236 | { // PCB shape for case
237 | if(useredge)outline(h,r);
238 | else hull()outline(h,r);
239 | }
240 |
241 | module pyramid()
242 | { // A pyramid
243 | polyhedron(points=[[0,0,0],[-height,-height,height],[-height,height,height],[height,height,height],[height,-height,height]],faces=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[4,3,2,1]]);
244 | }
245 |
246 | module wall(d=0)
247 | { // The case wall
248 | translate([0,0,-casebase-d])
249 | {
250 | if(useredge)
251 | intersection()
252 | {
253 | pcb(height+d*2,margin/2+d);
254 | pcbh(height+d*2,margin/2+d);
255 | }
256 | else pcbh(height+d*2,margin/2+d);
257 | }
258 | }
259 |
260 | module cutf()
261 | { // This cut up from base in the wall
262 | intersection()
263 | {
264 | boardf();
265 | difference()
266 | {
267 | translate([-casewall+0.01,-casewall+0.01,-casebase+0.01])cube([pcbwidth+casewall*2-0.02,pcblength+casewall*2-0.02,casebase+overlap+lip]);
268 | wall();
269 | boardb();
270 | }
271 | }
272 | }
273 |
274 | module cutb()
275 | { // The cut down from top in the wall
276 | intersection()
277 | {
278 | boardb();
279 | difference()
280 | {
281 | translate([-casewall+0.01,-casewall+0.01,0.01])cube([pcbwidth+casewall*2-0.02,pcblength+casewall*2-0.02,casetop+pcbthickness]);
282 | wall();
283 | boardf();
284 | }
285 | }
286 | }
287 |
288 | module cutpf()
289 | { // the push up but pyramid
290 | render()
291 | intersection()
292 | {
293 | minkowski()
294 | {
295 | pyramid();
296 | cutf();
297 | }
298 | difference()
299 | {
300 | translate([-casewall-0.01,-casewall-0.01,-casebase-0.01])cube([pcbwidth+casewall*2+0.02,pcblength+casewall*2+0.02,casebase+overlap+lip+0.02]);
301 | wall();
302 | boardh(true);
303 | }
304 | translate([-casewall,-casewall,-casebase])case();
305 | }
306 | }
307 |
308 | module cutpb()
309 | { // the push down but pyramid
310 | render()
311 | intersection()
312 | {
313 | minkowski()
314 | {
315 | scale([1,1,-1])pyramid();
316 | cutb();
317 | }
318 | difference()
319 | {
320 | translate([-casewall-0.01,-casewall-0.01,-0.01])cube([pcbwidth+casewall*2+0.02,pcblength+casewall*2+0.02,casetop+pcbthickness+0.02]);
321 | wall();
322 | boardh(true);
323 | }
324 | translate([-casewall,-casewall,-casebase])case();
325 | }
326 | }
327 |
328 | module case()
329 | { // The basic case
330 | hull()
331 | {
332 | translate([casewall,casewall,0])pcbh(height,casewall-edge);
333 | translate([casewall,casewall,edge])pcbh(height-edge*2,casewall);
334 | }
335 | }
336 |
337 | module cut(d=0)
338 | { // The cut point in the wall
339 | translate([casewall,casewall,casebase+lip])pcbh(casetop+pcbthickness-lip+1,casewall/2+d/2+margin/4);
340 | }
341 |
342 | module base()
343 | { // The base
344 | difference()
345 | {
346 | case();
347 | difference()
348 | {
349 | union()
350 | {
351 | translate([-1,-1,casebase+overlap+lip])cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,casetop+1]);
352 | cut(fit);
353 | }
354 | }
355 | translate([casewall,casewall,casebase])boardf();
356 | translate([casewall,casewall,casebase])boardm();
357 | translate([casewall,casewall,casebase])cutpf();
358 | }
359 | translate([casewall,casewall,casebase])cutpb();
360 | }
361 |
362 | module top()
363 | {
364 | translate([0,pcblength+casewall*2,height])rotate([180,0,0])
365 | {
366 | difference()
367 | {
368 | case();
369 | difference()
370 | {
371 | translate([-1,-1,-1])cube([pcbwidth+casewall*2+2,pcblength+casewall*2+2,casebase+overlap+lip-margin+1]);
372 | cut(-fit);
373 | }
374 | translate([casewall,casewall,casebase])boardb();
375 | translate([casewall,casewall,casebase])boardm();
376 | translate([casewall,casewall,casebase])cutpb();
377 | }
378 | translate([casewall,casewall,casebase])cutpf();
379 | }
380 | }
381 |
382 | module test()
383 | {
384 | translate([0*spacing,0,0])base();
385 | translate([1*spacing,0,0])top();
386 | translate([2*spacing,0,0])pcb();
387 | translate([3*spacing,0,0])outline();
388 | translate([4*spacing,0,0])wall();
389 | translate([5*spacing,0,0])board();
390 | translate([6*spacing,0,0])board(false,true);
391 | translate([7*spacing,0,0])board(true);
392 | translate([8*spacing,0,0])boardh();
393 | translate([9*spacing,0,0])boardf();
394 | translate([10*spacing,0,0])boardb();
395 | translate([11*spacing,0,0])cutpf();
396 | translate([12*spacing,0,0])cutpb();
397 | translate([13*spacing,0,0])cutf();
398 | translate([14*spacing,0,0])cutb();
399 | translate([15*spacing,0,0])case();
400 | }
401 |
402 | module parts()
403 | {
404 | base();
405 | translate([spacing,0,0])top();
406 | }
407 | base();
408 | translate([spacing,0,0])difference(){top();translate([casewall+pcbwidth/2-13/2,casewall+pcblength/2+6.5-5/2,-1])cube([15.5,5,10]);}
409 |
--------------------------------------------------------------------------------
/PCB/Round/production/bom.csv:
--------------------------------------------------------------------------------
1 | Designator,Footprint,Quantity,Value,LCSC Part #
2 | "C1, C2",C_0603,2,160pF,
3 | "C10, C13, C15",C_0603,3,4.7uF,
4 | "C11, C12, C14, C18, C7, C9",C_0603,6,100nF,
5 | "C16, C17, C3, C4",C_0603,4,22pF,
6 | C19,C_0603,1,33pF,
7 | C20,C_1206,1,100uF 6.3V,
8 | "C5, C6",C_0603,2,220pF,
9 | C8,C_0603,1,1nF,
10 | D1,LED_1206_Rev_Square,1,G,C157737
11 | "D10, D4, D5, D6, D7, D8, D9",DFN1006-2L,7,~,C5137770
12 | D2,LED_1206_Rev_Square,1,A,C125108
13 | D3,LED_1206_Rev_Square,1,R,C125107
14 | J3,PinHeader_1x05_P2.54mm_Vertical_SMD_Pin1Left,1,Conn,C780063
15 | "L1, L2",1008,2,560nH,C75639
16 | "R1, R3",R_0603_,2,0R,
17 | "R10, R12, R13, R14, R8, R9",R_0603,6,100R,
18 | "R11, R15, R6",R_0603,3,10K,
19 | R2,R_0805_,1,0R,
20 | R4,R_0603,1,2k7 1%,C114612
21 | R5,R_0603,1,1k 1%,C22548
22 | R7,R_0603,1,20K,
23 | SW1,ESE13,1,ESE13V01D,
24 | U1,QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm,1,PN532,
25 | Y1,Crystal-3.2x2.5,1,27.12MHz,C70591
26 |
--------------------------------------------------------------------------------
/PCB/Round/production/designators.csv:
--------------------------------------------------------------------------------
1 | A1:1
2 | C1:1
3 | C10:1
4 | C11:1
5 | C12:1
6 | C13:1
7 | C14:1
8 | C15:1
9 | C16:1
10 | C17:1
11 | C18:1
12 | C19:1
13 | C2:1
14 | C20:1
15 | C3:1
16 | C4:1
17 | C5:1
18 | C6:1
19 | C7:1
20 | C8:1
21 | C9:1
22 | D1:1
23 | D10:1
24 | D2:1
25 | D3:1
26 | D4:1
27 | D5:1
28 | D6:1
29 | D7:1
30 | D8:1
31 | D9:1
32 | J3:1
33 | JP1:1
34 | L1:1
35 | L2:1
36 | PCB1:1
37 | R1:1
38 | R10:1
39 | R11:1
40 | R12:1
41 | R13:1
42 | R14:1
43 | R15:1
44 | R2:1
45 | R3:1
46 | R4:1
47 | R5:1
48 | R6:1
49 | R7:1
50 | R8:1
51 | R9:1
52 | SW1:1
53 | U1:1
54 | U2:1
55 | V1:1
56 | V2:1
57 | V3:1
58 | V4:1
59 | Y1:1
60 |
--------------------------------------------------------------------------------
/PCB/Round/production/gerber.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Round/production/gerber.zip
--------------------------------------------------------------------------------
/PCB/Round/production/netlist.ipc:
--------------------------------------------------------------------------------
1 | P CODE 00
2 | P UNITS CUST 0
3 | P arrayDim N
4 | 317GND VIA MD0157PA00X+014843Y+011772X0315Y0000R000S3
5 | 317GND VIA MD0157PA00X+011024Y+013727X0315Y0000R000S3
6 | 317GND VIA MD0157PA00X+014173Y+014724X0315Y0000R000S3
7 | 317GND VIA MD0157PA00X+015950Y+014802X0315Y0000R000S3
8 | 317GND VIA MD0157PA00X+013740Y+011811X0315Y0000R000S3
9 | 317GND VIA MD0157PA00X+013780Y+017959X0315Y0000R000S3
10 | 317GND VIA MD0157PA00X+015043Y+013704X0315Y0000R000S3
11 | 317GND VIA MD0157PA00X+018071Y+013268X0315Y0000R000S3
12 | 317GND VIA MD0157PA00X+013780Y+015118X0315Y0000R000S3
13 | 317GND VIA MD0157PA00X+018071Y+011299X0315Y0000R000S3
14 | 317GND VIA MD0157PA00X+013386Y+015528X0315Y0000R000S3
15 | 317GND VIA MD0157PA00X+013386Y+014740X0315Y0000R000S3
16 | 317GND VIA MD0157PA00X+016024Y+013858X0315Y0000R000S3
17 | 317GND VIA MD0157PA00X+018071Y+016535X0315Y0000R000S3
18 | 317GND VIA MD0157PA00X+012620Y+013804X0315Y0000R000S3
19 | 317GND VIA MD0157PA00X+014843Y+016654X0315Y0000R000S3
20 | 317GND VIA MD0157PA00X+016181Y+012382X0315Y0000R000S3
21 | 317GND VIA MD0157PA00X+018071Y+015236X0315Y0000R000S3
22 | 317GND VIA MD0157PA00X+012283Y+012126X0315Y0000R000S3
23 | 317GND VIA MD0157PA00X+014173Y+015528X0315Y0000R000S3
24 | 317GND VIA MD0157PA00X+015945Y+015945X0315Y0000R000S3
25 | 317GND VIA MD0157PA00X+012185Y+015852X0315Y0000R000S3
26 | 317+5V VIA MD0157PA00X+015787Y+016496X0315Y0000R000S3
27 | 317+5V VIA MD0157PA00X+013701Y+012205X0315Y0000R000S3
28 | 317NET-(U1-VMID) VIA MD0157PA00X+011496Y+017614X0315Y0000R000S3
29 | 317NET-(U1-VMID) VIA MD0157PA00X+012372Y+016738X0315Y0000R000S3
30 | 317+3.3V VIA MD0157PA00X+016831Y+013445X0315Y0000R000S3
31 | 317+3.3V VIA MD0157PA00X+016575Y+015866X0315Y0000R000S3
32 | 317+3.3V VIA MD0157PA00X+012736Y+017024X0315Y0000R000S3
33 | 317+3.3V VIA MD0157PA00X+010846Y+012602X0315Y0000R000S3
34 | 317+3.3V VIA MD0157PA00X+010709Y+017949X0315Y0000R000S3
35 | 317+3.3V VIA MD0157PA00X+013592Y+017228X0315Y0000R000S3
36 | 327NET-(U1-OSCIN) Y1 -1 A01X+011024Y+015587X0512Y0413R270S2
37 | 327GND Y1 -2 A01X+011024Y+014681X0512Y0413R270S2
38 | 327ET-(U1-OSCOUT) Y1 -3 A01X+011713Y+014681X0512Y0413R270S2
39 | 327GND Y1 -4 A01X+011713Y+015587X0512Y0413R270S2
40 | 327GND D2 -1 A01X+018701Y+013268X0630Y0315R000S2
41 | 327NET-(D2-A) D2 -2 A01X+018701Y+014291X0630Y0315R000S2
42 | 327GND D3 -1 A01X+018701Y+015236X0630Y0315R000S2
43 | 327NET-(D3-A) D3 -2 A01X+018701Y+016260X0630Y0315R000S2
44 | 327N/C SW1 A01X+009173Y+013140X0276Y0413R180S2
45 | 327N/C SW1 A01X+009173Y+014419X0276Y0413R180S2
46 | 327GND SW1 -1 A01X+010354Y+013140X0276Y0413R180S2
47 | 327SLASH}UART_RX) SW1 -2 A01X+010354Y+014419X0276Y0413R180S2
48 | 327GND D1 -1 A01X+018701Y+011299X0630Y0315R000S2
49 | 327NET-(D1-A) D1 -2 A01X+018701Y+012323X0630Y0315R000S2
50 | 327+3.3V C7 -1 A01X+014016Y+017024X0315Y0374R000S2
51 | 327GND C7 -2 A01X+014626Y+017024X0315Y0374R000S2
52 | 327NET-(C3-PAD1) C3 -1 A01X+015276Y+019911X0315Y0374R270S2
53 | 327NET-(A1-PAD1) C3 -2 A01X+015276Y+020522X0315Y0374R270S2
54 | 327GND C5 -1 A01X+014144Y+019921X0315Y0374R000S2
55 | 327NET-(C3-PAD1) C5 -2 A01X+014754Y+019921X0315Y0374R000S2
56 | 327T-(U1-RSTPD_N) R6 -1 A01X+016998Y+016181X0315Y0374R000S2
57 | 327+5V R6 -2 A01X+017648Y+016181X0315Y0374R000S2
58 | 327NET-(C8-PAD2) R4 -1 A01X+011053Y+019921X0315Y0374R000S2
59 | 327NET-(C4-PAD2) R4 -2 A01X+011703Y+019921X0315Y0374R000S2
60 | 327+3.3V C13 -1 A01X+016201Y+015596X0315Y0374R090S2
61 | 327GND C13 -2 A01X+016201Y+014986X0315Y0374R090S2
62 | 327+5V C14 -1 A01X+015600Y+016197X0315Y0374R000S2
63 | 327GND C14 -2 A01X+016211Y+016197X0315Y0374R000S2
64 | 327NET-(U1-VMID) C9 -1 A01X+011063Y+017201X0315Y0374R000S2
65 | 327GND C9 -2 A01X+011673Y+017201X0315Y0374R000S2
66 | 327NET-(U1-OSCIN) C16 -1 A01X+011063Y+016118X0315Y0374R000S2
67 | 327GND C16 -2 A01X+011673Y+016118X0315Y0374R000S2
68 | 327-(U1-P32_INT0) R9 -1 A01X+016998Y+014764X0315Y0374R000S2
69 | 327NET-(D2-A) R9 -2 A01X+017648Y+014764X0315Y0374R000S2
70 | 327{SLASH}DBG_TX) R8 -1 A01X+016998Y+014291X0315Y0374R000S2
71 | 327NET-(D1-A) R8 -2 A01X+017648Y+014291X0315Y0374R000S2
72 | 327+3.3V R11 -1 A01X+013504Y+012781X0315Y0374R270S2
73 | 327SLASH}UART_RX) R11 -2 A01X+013504Y+013431X0315Y0374R270S2
74 | 327GND U1 -1 A01X+014665Y+016276X0276Y0098R090S2
75 | 327-LOADMOD-PAD2) U1 -2 A01X+014469Y+016276X0276Y0098R090S2
76 | 327GND U1 -3 A01X+014272Y+016276X0276Y0098R090S2
77 | 327NET-(U1-TX1) U1 -4 A01X+014075Y+016276X0276Y0098R090S2
78 | 327+3.3V U1 -5 A01X+013878Y+016276X0276Y0098R090S2
79 | 327NET-(U1-TX2) U1 -6 A01X+013681Y+016276X0276Y0098R090S2
80 | 327GND U1 -7 A01X+013484Y+016276X0276Y0098R090S2
81 | 327+3.3V U1 -8 A01X+013287Y+016276X0276Y0098R090S2
82 | 327NET-(U1-VMID) U1 -9 A01X+013091Y+016276X0276Y0098R090S2
83 | 327NET-(U1-RX) U1 -10 A01X+012894Y+016276X0276Y0098R090S2
84 | 327GND U1 -11 A01X+012638Y+016020X0098Y0276R090S2
85 | 327U1-AUX1-PAD12) U1 -12 A01X+012638Y+015823X0098Y0276R090S2
86 | 327U1-AUX2-PAD13) U1 -13 A01X+012638Y+015626X0098Y0276R090S2
87 | 327NET-(U1-OSCIN) U1 -14 A01X+012638Y+015429X0098Y0276R090S2
88 | 327ET-(U1-OSCOUT) U1 -15 A01X+012638Y+015232X0098Y0276R090S2
89 | 327GND U1 -16 A01X+012638Y+015035X0098Y0276R090S2
90 | 327NET-(JP1-C) U1 -17 A01X+012638Y+014839X0098Y0276R090S2
91 | 327GND U1 -18 A01X+012638Y+014642X0098Y0276R090S2
92 | 327(U1-P35-PAD19) U1 -19 A01X+012638Y+014445X0098Y0276R090S2
93 | 327-(U1-NC-PAD20) U1 -20 A01X+012638Y+014248X0098Y0276R090S2
94 | 327-(U1-NC-PAD21) U1 -21 A01X+012894Y+013992X0276Y0098R090S2
95 | 327-(U1-NC-PAD22) U1 -22 A01X+013091Y+013992X0276Y0098R090S2
96 | 327+3.3V U1 -23 A01X+013287Y+013992X0276Y0098R090S2
97 | 327SLASH}UART_RX) U1 -24 A01X+013484Y+013992X0276Y0098R090S2
98 | 327P70_IRQ-PAD25) U1 -25 A01X+013681Y+013992X0276Y0098R090S2
99 | 327STOUT_N-PAD26) U1 -26 A01X+013878Y+013992X0276Y0098R090S2
100 | 327{SLASH}HSU_RX) U1 -27 A01X+014075Y+013992X0276Y0098R090S2
101 | 327{SLASH}HSU_TX) U1 -28 A01X+014272Y+013992X0276Y0098R090S2
102 | 327ASH}P71-PAD29) U1 -29 A01X+014469Y+013992X0276Y0098R090S2
103 | 327SCK{SLASH}P72) U1 -30 A01X+014665Y+013992X0276Y0098R090S2
104 | 327{SLASH}DBG_TX) U1 -31 A01X+014921Y+014248X0098Y0276R090S2
105 | 327-(U1-P32_INT0) U1 -32 A01X+014921Y+014445X0098Y0276R090S2
106 | 327-(U1-P33_INT1) U1 -33 A01X+014921Y+014642X0098Y0276R090S2
107 | 327SIG_CLK-PAD34) U1 -34 A01X+014921Y+014839X0098Y0276R090S2
108 | 327-SIGOUT-PAD35) U1 -35 A01X+014921Y+015035X0098Y0276R090S2
109 | 327U1-SIGN-PAD36) U1 -36 A01X+014921Y+015232X0098Y0276R090S2
110 | 327U1-SVDD-PAD37) U1 -37 A01X+014921Y+015429X0098Y0276R090S2
111 | 327T-(U1-RSTPD_N) U1 -38 A01X+014921Y+015626X0098Y0276R090S2
112 | 327+3.3V U1 -39 A01X+014921Y+015823X0098Y0276R090S2
113 | 327+5V U1 -40 A01X+014921Y+016020X0098Y0276R090S2
114 | 327GND U1 -41 A01X+013780Y+015134X1732Y1732R090S2
115 | 327ET-(U1-OSCOUT) C17 -1 A01X+011673Y+014150X0315Y0374R180S2
116 | 327GND C17 -2 A01X+011063Y+014150X0315Y0374R180S2
117 | 327+3.3V C12 -1 A01X+013543Y+017555X0315Y0374R180S2
118 | 327GND C12 -2 A01X+012933Y+017555X0315Y0374R180S2
119 | 327NET-(U1-RX) R5 -1 A01X+011063Y+018274X0315Y0374R090S2
120 | 327NET-(U1-VMID) R5 -2 A01X+011063Y+017624X0315Y0374R090S2
121 | 327T-(U1-RSTPD_N) R7 -1 A01X+016998Y+015709X0315Y0374R000S2
122 | 327GND R7 -2 A01X+017648Y+015709X0315Y0374R000S2
123 | 327-(U1-P33_INT1) R10 -1 A01X+016998Y+015236X0315Y0374R000S2
124 | 327NET-(D3-A) R10 -2 A01X+017648Y+015236X0315Y0374R000S2
125 | 327+3.3V C18 -1 A01X+012874Y+012801X0315Y0374R270S2
126 | 327GND C18 -2 A01X+012874Y+013411X0315Y0374R270S2
127 | 327+3.3V C11 -1 A01X+015610Y+015596X0315Y0374R090S2
128 | 327GND C11 -2 A01X+015610Y+014986X0315Y0374R090S2
129 | 327NET-(U1-RX) C8 -1 A01X+011063Y+018687X0315Y0374R270S2
130 | 327NET-(C8-PAD2) C8 -2 A01X+011063Y+019297X0315Y0374R270S2
131 | 327GND J3 -1 A01X+012280Y+010569X0988Y0394R270S2
132 | 327+5V J3 -2 A01X+013280Y+011872X0988Y0394R270S2
133 | 327NET-(J3-PIN_3) J3 -3 A01X+014280Y+010569X0988Y0394R270S2
134 | 327NET-(J3-PIN_4) J3 -4 A01X+015280Y+011872X0988Y0394R270S2
135 | 327NET-(J3-PIN_5) J3 -5 A01X+016280Y+010569X0988Y0394R270S2
136 | 327+3.3V C10 -1 A01X+014016Y+017555X0315Y0374R000S2
137 | 327GND C10 -2 A01X+014626Y+017555X0315Y0374R000S2
138 | 327NET-(A1-PAD1) C1 -1 A01X+014754Y+020526X0315Y0374R180S2
139 | 327GND C1 -2 A01X+014144Y+020526X0315Y0374R180S2
140 | 327GND C6 -1 A01X+013415Y+019921X0315Y0374R180S2
141 | 327NET-(C4-PAD2) C6 -2 A01X+012805Y+019921X0315Y0374R180S2
142 | 327GND JP1 -1 A01X+011161Y+013008X0394Y0197R000S2
143 | 327NET-(JP1-C) JP1 -2 A01X+011673Y+013008X0394Y0591R000S2
144 | 327+3.3V JP1 -3 A01X+012185Y+013008X0394Y0197R000S2
145 | 327NET-(J3-PIN_3) R13 -1 A01X+014104Y+012811X0315Y0374R000S2
146 | 327{SLASH}HSU_TX) R13 -2 A01X+014754Y+012811X0315Y0374R000S2
147 | 327+3.3V C15 -1 A01X+011063Y+016669X0315Y0374R000S2
148 | 327GND C15 -2 A01X+011673Y+016669X0315Y0374R000S2
149 | 327NET-(J3-PIN_4) R14 -1 A01X+014754Y+013402X0315Y0374R180S2
150 | 327{SLASH}HSU_RX) R14 -2 A01X+014104Y+013402X0315Y0374R180S2
151 | 327NET-(U1-TX1) L1 -1 A01X+014760Y+018378X0492Y0866R315S2
152 | 327NET-(C3-PAD1) L1 -2 A01X+015358Y+018976X0492Y0866R315S2
153 | 327NET-(C4-PAD2) L2 -1 A01X+012201Y+018976X0492Y0866R045S2
154 | 327NET-(U1-TX2) L2 -2 A01X+012799Y+018378X0492Y0866R045S2
155 | 327NET-(A1-PAD3) C4 -1 A01X+012283Y+020522X0315Y0374R090S2
156 | 327NET-(C4-PAD2) C4 -2 A01X+012283Y+019911X0315Y0374R090S2
157 | 327NET-(J3-PIN_5) R12 -1 A01X+015906Y+013435X0315Y0374R090S2
158 | 327SCK{SLASH}P72) R12 -2 A01X+015906Y+012785X0315Y0374R090S2
159 | 327NET-(D2-A) D5 -1 A01X+018701Y+014596X0217Y0256R270S2
160 | 327GND D5 -2 A01X+018701Y+014931X0217Y0256R270S2
161 | 327N/C U2 -- A01X+013228Y+008071X0551Y0079R000S3
162 | 327N/C U2 -- A01X+013701Y+008189X0079Y0315R000S3
163 | 327N/C U2 -- A01X+013937Y+008071X0079Y0079R000S3
164 | 327N/C U2 -- A01X+014331Y+008071X0551Y0079R000S3
165 | 327N/C U2 -- A01X+012992Y+008346X0079Y0472R000S3
166 | 327N/C U2 -- A01X+013465Y+008346X0079Y0472R000S3
167 | 327N/C U2 -- A01X+013622Y+008189X0079Y0157R000S3
168 | 327N/C U2 -- A01X+013858Y+008228X0079Y0236R000S3
169 | 327N/C U2 -- A01X+014094Y+008346X0079Y0472R000S3
170 | 327N/C U2 -- A01X+014567Y+008346X0079Y0472R000S3
171 | 327N/C U2 -- A01X+013228Y+008307X0236Y0236R000S3
172 | 327N/C U2 -- A01X+013937Y+008228X0079Y0079R000S3
173 | 327N/C U2 -- A01X+014331Y+008307X0236Y0236R000S3
174 | 327N/C U2 -- A01X+013622Y+008504X0079Y0315R000S3
175 | 327N/C U2 -- A01X+013937Y+008504X0079Y0157R000S3
176 | 327N/C U2 -- A01X+013228Y+008543X0394Y0079R000S3
177 | 327N/C U2 -- A01X+013780Y+008661X0079Y0315R000S3
178 | 327N/C U2 -- A01X+014331Y+008543X0394Y0079R000S3
179 | 327N/C U2 -- A01X+013701Y+008661X0079Y0157R000S3
180 | 327N/C U2 -- A01X+013858Y+008701X0079Y0236R000S3
181 | 327N/C U2 -- A01X+013031Y+008740X0157Y0157R000S3
182 | 327N/C U2 -- A01X+013228Y+008701X0079Y0079R000S3
183 | 327N/C U2 -- A01X+013504Y+008701X0157Y0079R000S3
184 | 327N/C U2 -- A01X+013937Y+008701X0079Y0079R000S3
185 | 327N/C U2 -- A01X+014173Y+008701X0236Y0079R000S3
186 | 327N/C U2 -- A01X+014449Y+008740X0157Y0157R000S3
187 | 327N/C U2 -- A01X+013386Y+008780X0079Y0079R000S3
188 | 327N/C U2 -- A01X+014094Y+008819X0079Y0157R000S3
189 | 327N/C U2 -- A01X+014331Y+008780X0079Y0079R000S3
190 | 327N/C U2 -- A01X+014567Y+008780X0079Y0079R000S3
191 | 327N/C U2 -- A01X+013150Y+008858X0079Y0079R000S3
192 | 327N/C U2 -- A01X+013307Y+008937X0079Y0236R000S3
193 | 327N/C U2 -- A01X+013465Y+008858X0079Y0079R000S3
194 | 327N/C U2 -- A01X+013622Y+009016X0079Y0394R000S3
195 | 327N/C U2 -- A01X+013976Y+008898X0157Y0157R000S3
196 | 327N/C U2 -- A01X+014488Y+008858X0079Y0079R000S3
197 | 327N/C U2 -- A01X+013071Y+008937X0079Y0079R000S3
198 | 327N/C U2 -- A01X+013228Y+008937X0079Y0079R000S3
199 | 327N/C U2 -- A01X+013386Y+008976X0079Y0157R000S3
200 | 327N/C U2 -- A01X+013543Y+008976X0079Y0157R000S3
201 | 327N/C U2 -- A01X+013858Y+008976X0079Y0157R000S3
202 | 327N/C U2 -- A01X+014173Y+008976X0079Y0157R000S3
203 | 327N/C U2 -- A01X+014331Y+008937X0079Y0079R000S3
204 | 327N/C U2 -- A01X+014567Y+009094X0079Y0394R000S3
205 | 327N/C U2 -- A01X+013465Y+009016X0079Y0079R000S3
206 | 327N/C U2 -- A01X+013740Y+009016X0157Y0079R000S3
207 | 327N/C U2 -- A01X+014094Y+009016X0079Y0079R000S3
208 | 327N/C U2 -- A01X+013780Y+009291X0079Y0472R000S3
209 | 327N/C U2 -- A01X+013937Y+009134X0079Y0157R000S3
210 | 327N/C U2 -- A01X+014488Y+009094X0079Y0079R000S3
211 | 327N/C U2 -- A01X+013228Y+009173X0551Y0079R000S3
212 | 327N/C U2 -- A01X+013701Y+009173X0079Y0079R000S3
213 | 327N/C U2 -- A01X+014173Y+009173X0236Y0079R000S3
214 | 327N/C U2 -- A01X+014409Y+009173X0079Y0079R000S3
215 | 327N/C U2 -- A01X+012992Y+009449X0079Y0472R000S3
216 | 327N/C U2 -- A01X+013465Y+009449X0079Y0472R000S3
217 | 327N/C U2 -- A01X+013858Y+009252X0079Y0079R000S3
218 | 327N/C U2 -- A01X+014016Y+009252X0079Y0079R000S3
219 | 327N/C U2 -- A01X+014173Y+009291X0079Y0157R000S3
220 | 327N/C U2 -- A01X+014488Y+009331X0079Y0236R000S3
221 | 327N/C U2 -- A01X+013228Y+009409X0236Y0236R000S3
222 | 327N/C U2 -- A01X+013701Y+009488X0079Y0394R000S3
223 | 327N/C U2 -- A01X+014094Y+009370X0079Y0157R000S3
224 | 327N/C U2 -- A01X+014409Y+009331X0079Y0079R000S3
225 | 327N/C U2 -- A01X+013622Y+009409X0079Y0079R000S3
226 | 327N/C U2 -- A01X+013858Y+009488X0079Y0236R000S3
227 | 327N/C U2 -- A01X+014016Y+009409X0079Y0079R000S3
228 | 327N/C U2 -- A01X+014331Y+009409X0079Y0079R000S3
229 | 327N/C U2 -- A01X+014567Y+009488X0079Y0236R000S3
230 | 327N/C U2 -- A01X+014173Y+009488X0079Y0079R000S3
231 | 327N/C U2 -- A01X+013622Y+009606X0079Y0157R000S3
232 | 327N/C U2 -- A01X+013976Y+009567X0157Y0079R000S3
233 | 327N/C U2 -- A01X+014291Y+009567X0157Y0079R000S3
234 | 327N/C U2 -- A01X+013228Y+009646X0394Y0079R000S3
235 | 327N/C U2 -- A01X+013937Y+009646X0079Y0079R000S3
236 | 327N/C U2 -- A01X+014134Y+009646X0157Y0079R000S3
237 | 327{SLASH}HSU_RX) C19 -1 A01X+015315Y+012805X0315Y0374R270S2
238 | 327GND C19 -2 A01X+015315Y+013415X0315Y0374R270S2
239 | 327NET-(D1-A) D4 -1 A01X+018701Y+012628X0217Y0256R270S2
240 | 327GND D4 -2 A01X+018701Y+012963X0217Y0256R270S2
241 | 327NET-(J3-PIN_5) D6 -1 A01X+016742Y+012126X0217Y0256R180S2
242 | 327GND D6 -2 A01X+016407Y+012126X0217Y0256R180S2
243 | 327GND C20 -1 A01X+015285Y+016811X0453Y0709R000S2
244 | 327+5V C20 -2 A01X+016447Y+016811X0453Y0709R000S2
245 | 327NET-(D3-A) D7 -1 A01X+018701Y+016565X0217Y0256R270S2
246 | 327GND D7 -2 A01X+018701Y+016900X0217Y0256R270S2
247 | 327GND D8 -1 A01X+014094Y+012037X0217Y0256R270S2
248 | 327NET-(J3-PIN_3) D8 -2 A01X+014094Y+012372X0217Y0256R270S2
249 | 327GND C2 -1 A01X+013415Y+020526X0315Y0374R180S2
250 | 327NET-(A1-PAD3) C2 -2 A01X+012805Y+020526X0315Y0374R180S2
251 | 327NET-(J3-PIN_4) D9 -1 A01X+014764Y+012382X0217Y0256R090S2
252 | 327GND D9 -2 A01X+014764Y+012047X0217Y0256R090S2
253 | 367N/C PCB1 D0787UA00X+000984Y+026575X0787Y0000R000S0
254 | 367N/C PCB1 D0787UA00X+000984Y+000984X0787Y0000R000S0
255 | 327N/C PCB1 A01X+001969Y+026043X0394Y0000R000S3
256 | 327N/C PCB1 A02X+001969Y+026043X0394Y0000R000S1
257 | 327N/C PCB1 A01X+001969Y+001516X0394Y0000R000S3
258 | 327N/C PCB1 A02X+001969Y+001516X0394Y0000R000S1
259 | 327N/C PCB1 A01X+025591Y+026043X0394Y0000R000S3
260 | 327N/C PCB1 A02X+025591Y+026043X0394Y0000R000S1
261 | 327N/C PCB1 A01X+025591Y+001516X0394Y0000R000S3
262 | 327N/C PCB1 A02X+025591Y+001516X0394Y0000R000S1
263 | 367N/C PCB1 D0787UA00X+026575Y+026575X0787Y0000R000S0
264 | 367N/C PCB1 D0787UA00X+026575Y+000984X0787Y0000R000S0
265 | 327GND D10 -1 A01X+012589Y+012126X0217Y0256R000S2
266 | 327+5V D10 -2 A01X+012923Y+012126X0217Y0256R000S2
267 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+012787Y+021776X0197Y0000R000S3
268 | 3271-LOOP-PAD0)_7 A1 -0 A01X+013031Y+021776X0492Y0197R000S3
269 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+013406Y+022602X0197Y0000R000S3
270 | 3271-LOOP-PAD0)_7 A1 -0 A01X+013406Y+022602X0197Y0197R000S3
271 | 3271-LOOP-PAD0)_7 A1 -0 A00X+013780Y+022602X0748Y0197R000S3
272 | 3171-LOOP-PAD0)_7 A1 -0 D0098PA00X+014154Y+022602X0197Y0000R000S3
273 | 3271-LOOP-PAD0)_7 A1 -0 A02X+014154Y+022602X0197Y0197R000S3
274 | 3271-LOOP-PAD0)_7 A1 -0 A01X+014528Y+021776X0492Y0197R000S3
275 | 327NET-(A1-PAD1) A1 -1 A01X+014476Y+021146X0394Y0197R000S2
276 | 327GND A1 -2 A01X+013780Y+021815X0551Y0197R000S2
277 | 327NET-(A1-PAD3) A1 -3 A01X+013083Y+021146X0394Y0197R000S2
278 | 327+3.3V R15 -1 A01X+016457Y+013445X0315Y0374R090S2
279 | 327SCK{SLASH}P72) R15 -2 A01X+016457Y+012795X0315Y0374R090S2
280 | 999
281 |
--------------------------------------------------------------------------------
/PCB/Round/production/positions.csv:
--------------------------------------------------------------------------------
1 | Designator,Mid X,Mid Y,Rotation,Layer
2 | C1,36.7,52.135,180.0,top
3 | C10,36.375,44.59,0.0,top
4 | C11,39.65,38.84,270.0,top
5 | C12,33.625,44.59,180.0,top
6 | C13,41.15,38.84,270.0,top
7 | C14,40.4,41.14,0.0,top
8 | C15,28.875,42.34,0.0,top
9 | C16,28.875,40.94,0.0,top
10 | C17,28.875,35.94,180.0,top
11 | C18,32.7,33.29,90.0,top
12 | C19,38.9,33.3,90.0,top
13 | C2,33.3,52.135,180.0,top
14 | C20,40.3,42.7,0.0,top
15 | C3,38.8,51.35,90.0,top
16 | C4,31.2,51.35,270.0,top
17 | C5,36.7,50.6,0.0,top
18 | C6,33.3,50.6,180.0,top
19 | C7,36.375,43.24,0.0,top
20 | C8,28.1,48.24,90.0,top
21 | C9,28.875,43.69,0.0,top
22 | D1,47.5,30.0,90.0,top
23 | D10,32.4,30.8,0.0,top
24 | D2,47.5,35.0,90.0,top
25 | D3,47.5,40.0,90.0,top
26 | D4,47.5,32.5,90.0,top
27 | D5,47.5,37.5,90.0,top
28 | D6,42.1,30.8,180.0,top
29 | D7,47.5,42.5,90.0,top
30 | D8,35.8,31.0,90.0,top
31 | D9,37.5,31.025,270.0,top
32 | J3,36.27,28.5,90.0,top
33 | L1,38.25,47.44,45.0,top
34 | L2,31.75,47.44,315.0,top
35 | R1,33.23,54.51,90.0,top
36 | R10,44.0,38.7,0.0,top
37 | R11,34.3,33.29,90.0,top
38 | R12,40.4,33.3,270.0,top
39 | R13,36.65,32.54,0.0,top
40 | R14,36.65,34.04,180.0,top
41 | R15,41.8,33.325,270.0,top
42 | R2,35.0,56.41,90.0,top
43 | R3,36.77,54.51,90.0,top
44 | R4,28.9,50.6,0.0,top
45 | R5,28.1,45.59,270.0,top
46 | R6,44.0,41.1,0.0,top
47 | R7,44.0,39.9,0.0,top
48 | R8,44.0,36.3,0.0,top
49 | R9,44.0,37.5,0.0,top
50 | SW1,24.8,35.0,180.0,top
51 | U1,35.0,38.44,180.0,top
52 | Y1,28.875,38.44,90.0,top
53 |
--------------------------------------------------------------------------------
/PCB/Square/.gitignore:
--------------------------------------------------------------------------------
1 | *-backups
2 | *cache*
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/PCB/Square/README.md:
--------------------------------------------------------------------------------
1 | # Square
2 |
3 | These files are for use in [KiCad](https://www.kicad.org).
4 |
5 | ## Trademark
6 |
7 | This is an open source project, but bear in mind you cannot sell boards bearing the Andrews & Arnold Ltd name, the A&A logo, the registered trademark AJK logo, or the GS1 allocated EANs assigned to Andrews & Arnold Ltd.
8 |
9 | ## Images
10 |
11 | 

12 |
13 | *Auto generated 2025-01-19T12:52:54*
14 |
--------------------------------------------------------------------------------
/PCB/Square/Square-90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square-90.png
--------------------------------------------------------------------------------
/PCB/Square/Square-bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square-bottom.png
--------------------------------------------------------------------------------
/PCB/Square/Square.kicad_prl:
--------------------------------------------------------------------------------
1 | {
2 | "board": {
3 | "active_layer": 0,
4 | "active_layer_preset": "",
5 | "auto_track_width": true,
6 | "hidden_netclasses": [],
7 | "hidden_nets": [],
8 | "high_contrast_mode": 0,
9 | "net_color_mode": 1,
10 | "opacity": {
11 | "images": 0.6,
12 | "pads": 1.0,
13 | "shapes": 1.0,
14 | "tracks": 1.0,
15 | "vias": 1.0,
16 | "zones": 1.0
17 | },
18 | "ratsnest_display_mode": 0,
19 | "selection_filter": {
20 | "dimensions": true,
21 | "footprints": true,
22 | "graphics": true,
23 | "keepouts": true,
24 | "lockedItems": true,
25 | "otherItems": true,
26 | "pads": true,
27 | "text": true,
28 | "tracks": true,
29 | "vias": true,
30 | "zones": true
31 | },
32 | "visible_items": [
33 | 0,
34 | 1,
35 | 2,
36 | 3,
37 | 4,
38 | 5,
39 | 8,
40 | 9,
41 | 10,
42 | 11,
43 | 12,
44 | 13,
45 | 14,
46 | 15,
47 | 16,
48 | 17,
49 | 18,
50 | 19,
51 | 20,
52 | 21,
53 | 22,
54 | 23,
55 | 24,
56 | 25,
57 | 26,
58 | 27,
59 | 28,
60 | 29,
61 | 30,
62 | 32,
63 | 33,
64 | 34,
65 | 35,
66 | 36,
67 | 41
68 | ],
69 | "visible_layers": "0003d3fc_80000001",
70 | "zone_display_mode": 0
71 | },
72 | "git": {
73 | "repo_password": "",
74 | "repo_type": "",
75 | "repo_username": "",
76 | "ssh_key": ""
77 | },
78 | "meta": {
79 | "filename": "Square.kicad_prl",
80 | "version": 4
81 | },
82 | "net_inspector_panel": {
83 | "col_hidden": [
84 | false,
85 | false,
86 | false,
87 | false,
88 | false,
89 | false,
90 | false,
91 | false,
92 | false,
93 | false
94 | ],
95 | "col_order": [
96 | 0,
97 | 1,
98 | 2,
99 | 3,
100 | 4,
101 | 5,
102 | 6,
103 | 7,
104 | 8,
105 | 9
106 | ],
107 | "col_widths": [
108 | 156,
109 | 141,
110 | 103,
111 | 71,
112 | 103,
113 | 103,
114 | 103,
115 | 74,
116 | 103,
117 | 103
118 | ],
119 | "custom_group_rules": [],
120 | "expanded_rows": [],
121 | "filter_by_net_name": true,
122 | "filter_by_netclass": true,
123 | "filter_text": "",
124 | "group_by_constraint": false,
125 | "group_by_netclass": false,
126 | "show_unconnected_nets": false,
127 | "show_zero_pad_nets": false,
128 | "sort_ascending": true,
129 | "sorting_column": 0
130 | },
131 | "project": {
132 | "files": []
133 | },
134 | "schematic": {
135 | "selection_filter": {
136 | "graphics": true,
137 | "images": true,
138 | "labels": true,
139 | "lockedItems": false,
140 | "otherItems": true,
141 | "pins": true,
142 | "symbols": true,
143 | "text": true,
144 | "wires": true
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/PCB/Square/Square.kicad_pro:
--------------------------------------------------------------------------------
1 | {
2 | "board": {
3 | "3dviewports": [],
4 | "design_settings": {
5 | "defaults": {
6 | "apply_defaults_to_fp_fields": false,
7 | "apply_defaults_to_fp_shapes": false,
8 | "apply_defaults_to_fp_text": false,
9 | "board_outline_line_width": 0.05,
10 | "copper_line_width": 0.2,
11 | "copper_text_italic": false,
12 | "copper_text_size_h": 1.5,
13 | "copper_text_size_v": 1.5,
14 | "copper_text_thickness": 0.3,
15 | "copper_text_upright": false,
16 | "courtyard_line_width": 0.05,
17 | "dimension_precision": 4,
18 | "dimension_units": 3,
19 | "dimensions": {
20 | "arrow_length": 1270000,
21 | "extension_offset": 500000,
22 | "keep_text_aligned": true,
23 | "suppress_zeroes": false,
24 | "text_position": 0,
25 | "units_format": 1
26 | },
27 | "fab_line_width": 0.1,
28 | "fab_text_italic": false,
29 | "fab_text_size_h": 1.0,
30 | "fab_text_size_v": 1.0,
31 | "fab_text_thickness": 0.15,
32 | "fab_text_upright": false,
33 | "other_line_width": 0.1,
34 | "other_text_italic": false,
35 | "other_text_size_h": 1.0,
36 | "other_text_size_v": 1.0,
37 | "other_text_thickness": 0.15,
38 | "other_text_upright": false,
39 | "pads": {
40 | "drill": 0.0,
41 | "height": 1.2,
42 | "width": 0.5
43 | },
44 | "silk_line_width": 0.12,
45 | "silk_text_italic": false,
46 | "silk_text_size_h": 1.0,
47 | "silk_text_size_v": 1.0,
48 | "silk_text_thickness": 0.15,
49 | "silk_text_upright": false,
50 | "zones": {
51 | "45_degree_only": false,
52 | "min_clearance": 0.25
53 | }
54 | },
55 | "diff_pair_dimensions": [
56 | {
57 | "gap": 0.0,
58 | "via_gap": 0.0,
59 | "width": 0.0
60 | }
61 | ],
62 | "drc_exclusions": [],
63 | "meta": {
64 | "filename": "board_design_settings.json",
65 | "version": 2
66 | },
67 | "rule_severities": {
68 | "annular_width": "error",
69 | "clearance": "error",
70 | "connection_width": "warning",
71 | "copper_edge_clearance": "warning",
72 | "copper_sliver": "warning",
73 | "courtyards_overlap": "error",
74 | "creepage": "error",
75 | "diff_pair_gap_out_of_range": "error",
76 | "diff_pair_uncoupled_length_too_long": "error",
77 | "drill_out_of_range": "error",
78 | "duplicate_footprints": "warning",
79 | "extra_footprint": "warning",
80 | "footprint": "error",
81 | "footprint_filters_mismatch": "ignore",
82 | "footprint_symbol_mismatch": "warning",
83 | "footprint_type_mismatch": "error",
84 | "hole_clearance": "error",
85 | "hole_near_hole": "error",
86 | "hole_to_hole": "warning",
87 | "holes_co_located": "warning",
88 | "invalid_outline": "error",
89 | "isolated_copper": "warning",
90 | "item_on_disabled_layer": "error",
91 | "items_not_allowed": "error",
92 | "length_out_of_range": "error",
93 | "lib_footprint_issues": "warning",
94 | "lib_footprint_mismatch": "warning",
95 | "malformed_courtyard": "error",
96 | "microvia_drill_out_of_range": "error",
97 | "mirrored_text_on_front_layer": "warning",
98 | "missing_courtyard": "ignore",
99 | "missing_footprint": "warning",
100 | "net_conflict": "warning",
101 | "nonmirrored_text_on_back_layer": "warning",
102 | "npth_inside_courtyard": "ignore",
103 | "padstack": "error",
104 | "pth_inside_courtyard": "ignore",
105 | "shorting_items": "error",
106 | "silk_edge_clearance": "warning",
107 | "silk_over_copper": "warning",
108 | "silk_overlap": "warning",
109 | "skew_out_of_range": "error",
110 | "solder_mask_bridge": "error",
111 | "starved_thermal": "error",
112 | "text_height": "warning",
113 | "text_thickness": "warning",
114 | "through_hole_pad_without_hole": "error",
115 | "too_many_vias": "error",
116 | "track_angle": "error",
117 | "track_dangling": "warning",
118 | "track_segment_length": "error",
119 | "track_width": "error",
120 | "tracks_crossing": "error",
121 | "unconnected_items": "error",
122 | "unresolved_variable": "error",
123 | "via_dangling": "warning",
124 | "zone_has_empty_net": "error",
125 | "zones_intersect": "error"
126 | },
127 | "rule_severitieslegacy_courtyards_overlap": true,
128 | "rule_severitieslegacy_no_courtyard_defined": false,
129 | "rules": {
130 | "allow_blind_buried_vias": false,
131 | "allow_microvias": false,
132 | "max_error": 0.005,
133 | "min_clearance": 0.125,
134 | "min_connection": 0.0,
135 | "min_copper_edge_clearance": 0.2,
136 | "min_groove_width": 0.0,
137 | "min_hole_clearance": 0.125,
138 | "min_hole_to_hole": 0.2,
139 | "min_microvia_diameter": 0.3,
140 | "min_microvia_drill": 0.2,
141 | "min_resolved_spokes": 2,
142 | "min_silk_clearance": 0.0,
143 | "min_text_height": 0.8,
144 | "min_text_thickness": 0.08,
145 | "min_through_hole_diameter": 0.2,
146 | "min_track_width": 0.125,
147 | "min_via_annular_width": 0.05,
148 | "min_via_diameter": 0.4,
149 | "solder_mask_to_copper_clearance": 0.0,
150 | "use_height_for_length_calcs": true
151 | },
152 | "teardrop_options": [
153 | {
154 | "td_onpthpad": true,
155 | "td_onroundshapesonly": false,
156 | "td_onsmdpad": true,
157 | "td_ontrackend": false,
158 | "td_onvia": true
159 | }
160 | ],
161 | "teardrop_parameters": [
162 | {
163 | "td_allow_use_two_tracks": true,
164 | "td_curve_segcount": 0,
165 | "td_height_ratio": 1.0,
166 | "td_length_ratio": 0.5,
167 | "td_maxheight": 2.0,
168 | "td_maxlen": 1.0,
169 | "td_on_pad_in_zone": false,
170 | "td_target_name": "td_round_shape",
171 | "td_width_to_size_filter_ratio": 0.9
172 | },
173 | {
174 | "td_allow_use_two_tracks": true,
175 | "td_curve_segcount": 0,
176 | "td_height_ratio": 1.0,
177 | "td_length_ratio": 0.5,
178 | "td_maxheight": 2.0,
179 | "td_maxlen": 1.0,
180 | "td_on_pad_in_zone": false,
181 | "td_target_name": "td_rect_shape",
182 | "td_width_to_size_filter_ratio": 0.9
183 | },
184 | {
185 | "td_allow_use_two_tracks": true,
186 | "td_curve_segcount": 0,
187 | "td_height_ratio": 1.0,
188 | "td_length_ratio": 0.5,
189 | "td_maxheight": 2.0,
190 | "td_maxlen": 1.0,
191 | "td_on_pad_in_zone": false,
192 | "td_target_name": "td_track_end",
193 | "td_width_to_size_filter_ratio": 0.9
194 | }
195 | ],
196 | "track_widths": [
197 | 0.0,
198 | 0.125,
199 | 0.2,
200 | 0.25,
201 | 0.3,
202 | 0.5
203 | ],
204 | "tuning_pattern_settings": {
205 | "diff_pair_defaults": {
206 | "corner_radius_percentage": 80,
207 | "corner_style": 1,
208 | "max_amplitude": 1.0,
209 | "min_amplitude": 0.2,
210 | "single_sided": false,
211 | "spacing": 1.0
212 | },
213 | "diff_pair_skew_defaults": {
214 | "corner_radius_percentage": 80,
215 | "corner_style": 1,
216 | "max_amplitude": 1.0,
217 | "min_amplitude": 0.2,
218 | "single_sided": false,
219 | "spacing": 0.6
220 | },
221 | "single_track_defaults": {
222 | "corner_radius_percentage": 80,
223 | "corner_style": 1,
224 | "max_amplitude": 1.0,
225 | "min_amplitude": 0.2,
226 | "single_sided": false,
227 | "spacing": 0.6
228 | }
229 | },
230 | "via_dimensions": [
231 | {
232 | "diameter": 0.0,
233 | "drill": 0.0
234 | }
235 | ],
236 | "zones_allow_external_fillets": false,
237 | "zones_use_no_outline": true
238 | },
239 | "ipc2581": {
240 | "dist": "",
241 | "distpn": "",
242 | "internal_id": "",
243 | "mfg": "",
244 | "mpn": ""
245 | },
246 | "layer_pairs": [],
247 | "layer_presets": [],
248 | "viewports": []
249 | },
250 | "boards": [],
251 | "cvpcb": {
252 | "equivalence_files": []
253 | },
254 | "erc": {
255 | "erc_exclusions": [],
256 | "meta": {
257 | "version": 0
258 | },
259 | "pin_map": [
260 | [
261 | 0,
262 | 0,
263 | 0,
264 | 0,
265 | 0,
266 | 0,
267 | 1,
268 | 0,
269 | 0,
270 | 0,
271 | 0,
272 | 2
273 | ],
274 | [
275 | 0,
276 | 2,
277 | 0,
278 | 1,
279 | 0,
280 | 0,
281 | 1,
282 | 0,
283 | 2,
284 | 2,
285 | 2,
286 | 2
287 | ],
288 | [
289 | 0,
290 | 0,
291 | 0,
292 | 0,
293 | 0,
294 | 0,
295 | 1,
296 | 0,
297 | 1,
298 | 0,
299 | 1,
300 | 2
301 | ],
302 | [
303 | 0,
304 | 1,
305 | 0,
306 | 0,
307 | 0,
308 | 0,
309 | 1,
310 | 1,
311 | 2,
312 | 1,
313 | 1,
314 | 2
315 | ],
316 | [
317 | 0,
318 | 0,
319 | 0,
320 | 0,
321 | 0,
322 | 0,
323 | 1,
324 | 0,
325 | 0,
326 | 0,
327 | 0,
328 | 2
329 | ],
330 | [
331 | 0,
332 | 0,
333 | 0,
334 | 0,
335 | 0,
336 | 0,
337 | 0,
338 | 0,
339 | 0,
340 | 0,
341 | 0,
342 | 2
343 | ],
344 | [
345 | 1,
346 | 1,
347 | 1,
348 | 1,
349 | 1,
350 | 0,
351 | 1,
352 | 1,
353 | 1,
354 | 1,
355 | 1,
356 | 2
357 | ],
358 | [
359 | 0,
360 | 0,
361 | 0,
362 | 1,
363 | 0,
364 | 0,
365 | 1,
366 | 0,
367 | 0,
368 | 0,
369 | 0,
370 | 2
371 | ],
372 | [
373 | 0,
374 | 2,
375 | 1,
376 | 2,
377 | 0,
378 | 0,
379 | 1,
380 | 0,
381 | 2,
382 | 2,
383 | 2,
384 | 2
385 | ],
386 | [
387 | 0,
388 | 2,
389 | 0,
390 | 1,
391 | 0,
392 | 0,
393 | 1,
394 | 0,
395 | 2,
396 | 0,
397 | 0,
398 | 2
399 | ],
400 | [
401 | 0,
402 | 2,
403 | 1,
404 | 1,
405 | 0,
406 | 0,
407 | 1,
408 | 0,
409 | 2,
410 | 0,
411 | 0,
412 | 2
413 | ],
414 | [
415 | 2,
416 | 2,
417 | 2,
418 | 2,
419 | 2,
420 | 2,
421 | 2,
422 | 2,
423 | 2,
424 | 2,
425 | 2,
426 | 2
427 | ]
428 | ],
429 | "rule_severities": {
430 | "bus_definition_conflict": "error",
431 | "bus_entry_needed": "error",
432 | "bus_label_syntax": "error",
433 | "bus_to_bus_conflict": "error",
434 | "bus_to_net_conflict": "error",
435 | "different_unit_footprint": "error",
436 | "different_unit_net": "error",
437 | "duplicate_reference": "error",
438 | "duplicate_sheet_names": "error",
439 | "endpoint_off_grid": "warning",
440 | "extra_units": "error",
441 | "footprint_filter": "ignore",
442 | "footprint_link_issues": "warning",
443 | "four_way_junction": "ignore",
444 | "global_label_dangling": "warning",
445 | "hier_label_mismatch": "error",
446 | "label_dangling": "error",
447 | "label_multiple_wires": "warning",
448 | "lib_symbol_issues": "warning",
449 | "lib_symbol_mismatch": "warning",
450 | "missing_bidi_pin": "warning",
451 | "missing_input_pin": "warning",
452 | "missing_power_pin": "error",
453 | "missing_unit": "warning",
454 | "multiple_net_names": "warning",
455 | "net_not_bus_member": "warning",
456 | "no_connect_connected": "warning",
457 | "no_connect_dangling": "warning",
458 | "pin_not_connected": "error",
459 | "pin_not_driven": "error",
460 | "pin_to_pin": "warning",
461 | "power_pin_not_driven": "error",
462 | "same_local_global_label": "warning",
463 | "similar_label_and_power": "warning",
464 | "similar_labels": "warning",
465 | "similar_power": "warning",
466 | "simulation_model_issue": "ignore",
467 | "single_global_label": "ignore",
468 | "unannotated": "error",
469 | "unconnected_wire_endpoint": "warning",
470 | "unit_value_mismatch": "error",
471 | "unresolved_variable": "error",
472 | "wire_dangling": "error"
473 | }
474 | },
475 | "libraries": {
476 | "pinned_footprint_libs": [],
477 | "pinned_symbol_libs": []
478 | },
479 | "meta": {
480 | "filename": "Square.kicad_pro",
481 | "version": 2
482 | },
483 | "net_settings": {
484 | "classes": [
485 | {
486 | "bus_width": 12,
487 | "clearance": 0.125,
488 | "diff_pair_gap": 0.25,
489 | "diff_pair_via_gap": 0.25,
490 | "diff_pair_width": 0.2,
491 | "line_style": 0,
492 | "microvia_diameter": 0.3,
493 | "microvia_drill": 0.1,
494 | "name": "Default",
495 | "pcb_color": "rgba(0, 0, 0, 0.000)",
496 | "priority": 2147483647,
497 | "schematic_color": "rgba(0, 0, 0, 0.000)",
498 | "track_width": 0.125,
499 | "via_diameter": 0.8,
500 | "via_drill": 0.4,
501 | "wire_width": 6
502 | },
503 | {
504 | "bus_width": 12,
505 | "clearance": 0.125,
506 | "diff_pair_gap": 0.25,
507 | "diff_pair_via_gap": 0.25,
508 | "diff_pair_width": 0.2,
509 | "line_style": 0,
510 | "microvia_diameter": 0.3,
511 | "microvia_drill": 0.1,
512 | "name": "Power",
513 | "pcb_color": "rgba(0, 0, 0, 0.000)",
514 | "priority": 0,
515 | "schematic_color": "rgba(0, 0, 0, 0.000)",
516 | "track_width": 0.25,
517 | "via_diameter": 0.8,
518 | "via_drill": 0.4,
519 | "wire_width": 6
520 | }
521 | ],
522 | "meta": {
523 | "version": 4
524 | },
525 | "net_colors": null,
526 | "netclass_assignments": null,
527 | "netclass_patterns": [
528 | {
529 | "netclass": "Power",
530 | "pattern": "GND"
531 | }
532 | ]
533 | },
534 | "pcbnew": {
535 | "last_paths": {
536 | "gencad": "",
537 | "idf": "",
538 | "netlist": "",
539 | "plot": "",
540 | "pos_files": "",
541 | "specctra_dsn": "",
542 | "step": "",
543 | "svg": "",
544 | "vrml": ""
545 | },
546 | "page_layout_descr_file": ""
547 | },
548 | "schematic": {
549 | "annotate_start_num": 0,
550 | "bom_export_filename": "${PROJECTNAME}.csv",
551 | "bom_fmt_presets": [],
552 | "bom_fmt_settings": {
553 | "field_delimiter": ",",
554 | "keep_line_breaks": false,
555 | "keep_tabs": false,
556 | "name": "CSV",
557 | "ref_delimiter": ",",
558 | "ref_range_delimiter": "",
559 | "string_delimiter": "\""
560 | },
561 | "bom_presets": [],
562 | "bom_settings": {
563 | "exclude_dnp": false,
564 | "fields_ordered": [
565 | {
566 | "group_by": false,
567 | "label": "Reference",
568 | "name": "Reference",
569 | "show": true
570 | },
571 | {
572 | "group_by": false,
573 | "label": "Qty",
574 | "name": "${QUANTITY}",
575 | "show": true
576 | },
577 | {
578 | "group_by": true,
579 | "label": "Value",
580 | "name": "Value",
581 | "show": true
582 | },
583 | {
584 | "group_by": true,
585 | "label": "DNP",
586 | "name": "${DNP}",
587 | "show": true
588 | },
589 | {
590 | "group_by": true,
591 | "label": "Exclude from BOM",
592 | "name": "${EXCLUDE_FROM_BOM}",
593 | "show": true
594 | },
595 | {
596 | "group_by": true,
597 | "label": "Exclude from Board",
598 | "name": "${EXCLUDE_FROM_BOARD}",
599 | "show": true
600 | },
601 | {
602 | "group_by": true,
603 | "label": "Footprint",
604 | "name": "Footprint",
605 | "show": true
606 | },
607 | {
608 | "group_by": false,
609 | "label": "Datasheet",
610 | "name": "Datasheet",
611 | "show": true
612 | }
613 | ],
614 | "filter_string": "",
615 | "group_symbols": true,
616 | "include_excluded_from_bom": true,
617 | "name": "Default Editing",
618 | "sort_asc": true,
619 | "sort_field": "Reference"
620 | },
621 | "connection_grid_size": 50.0,
622 | "drawing": {
623 | "dashed_lines_dash_length_ratio": 12.0,
624 | "dashed_lines_gap_length_ratio": 3.0,
625 | "default_line_thickness": 6.0,
626 | "default_text_size": 50.0,
627 | "field_names": [],
628 | "intersheets_ref_own_page": false,
629 | "intersheets_ref_prefix": "",
630 | "intersheets_ref_short": false,
631 | "intersheets_ref_show": false,
632 | "intersheets_ref_suffix": "",
633 | "junction_size_choice": 3,
634 | "label_size_ratio": 0.25,
635 | "operating_point_overlay_i_precision": 3,
636 | "operating_point_overlay_i_range": "~A",
637 | "operating_point_overlay_v_precision": 3,
638 | "operating_point_overlay_v_range": "~V",
639 | "overbar_offset_ratio": 1.23,
640 | "pin_symbol_size": 25.0,
641 | "text_offset_ratio": 0.08
642 | },
643 | "legacy_lib_dir": "",
644 | "legacy_lib_list": [],
645 | "meta": {
646 | "version": 1
647 | },
648 | "net_format_name": "",
649 | "ngspice": {
650 | "fix_include_paths": true,
651 | "fix_passive_vals": false,
652 | "meta": {
653 | "version": 0
654 | },
655 | "model_mode": 0,
656 | "workbook_filename": ""
657 | },
658 | "page_layout_descr_file": "",
659 | "plot_directory": "",
660 | "space_save_all_events": true,
661 | "spice_adjust_passive_values": false,
662 | "spice_current_sheet_as_root": false,
663 | "spice_external_command": "spice \"%I\"",
664 | "spice_model_current_sheet_as_root": true,
665 | "spice_save_all_currents": false,
666 | "spice_save_all_dissipations": false,
667 | "spice_save_all_voltages": false,
668 | "subpart_first_id": 65,
669 | "subpart_id_separator": 0
670 | },
671 | "sheets": [
672 | [
673 | "0217dfc4-fc13-4699-99ad-d9948522648e",
674 | "Root"
675 | ]
676 | ],
677 | "text_variables": {
678 | "DATE": "2022-08-05",
679 | "URL": "pn532.revk.uk"
680 | }
681 | }
682 |
--------------------------------------------------------------------------------
/PCB/Square/Square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/Square.png
--------------------------------------------------------------------------------
/PCB/Square/Square.scad:
--------------------------------------------------------------------------------
1 | // Case for NFC reader
2 | // Controls
3 | cover=0; // How much to cover the SMD LEDs on antenna side
4 | // Note it is assumed leaded components cut flush
5 | base=0; // How much extra base (e.g. for mounting off metal)
6 | thick=3; // Wall thickness
7 | led=1; // LED/front thickness
8 |
9 | raspox=true; // Right angle SPOX side cable
10 | spox=true; // Straight SPOX rear
11 | tamper=true; // Tamper button fitted
12 | tamperth=false; // Tamper is through hole
13 | bell=true; // Tamper 2 pin header rear
14 | screws=true;
15 |
16 | corner=8; // PCB corner radius
17 | chamfer=1; // Case chamfer
18 | size=20; // PCB size/2
19 | pcb=0.8; // PCB thickness
20 | slide=1; // Screw hold slide
21 |
22 | $fn=100;
23 |
24 | module b(cx,cy,z,w,l,h)
25 | {
26 | translate([cx-w/2,cy-l/2,z])cube([w,l,h]);
27 | }
28 |
29 | module base()
30 | {
31 | difference()
32 | {
33 | union()
34 | {
35 | hull()for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0])cylinder(r=corner+0.2,h=4.9+base);
36 | if(base>0)hull()for(x=[-12,12])for(y=[-12,12])translate([x,y,4.9])
37 | {
38 | if(base>1)translate([0,0,base-1])cylinder(r=9+thick+base-1,h=1);
39 | cylinder(r=corner+thick,h=base);
40 | }
41 | }
42 | translate([0,0,-0.1])hull()for(x=[-12,12])for(y=[-12,12])translate([x,y,0])cylinder(r=5,h=3);
43 | if(raspox)b(0,-8.9-6.6+7.9/2-2-20,-0.01,12.4+0.2,7.9+0.2+40,4.92);
44 | if(spox)b(0,-8.9+3.1-4.9/2,-0.01,12.4+0.5,4.9+0.5,5+base);
45 | if(tamper)b(-11.5,0,0,7,7,3.9); // Under 6x6 but SMD so may not be exact placement
46 | if(bell)b(12,-6,-0.01,4.82+0.4,5.64+0.4,5+base);
47 | if(screws)for(t=[-12,12])translate([t,-t,2.9])
48 | { // Screws in base
49 | hull()for(t=[-slide/2,slide/2])
50 | translate([t,t,-1])cylinder(d=3.5,h=3+base+2);
51 | hull()for(t=[-slide/2,slide/2])
52 | translate([t,t,-0.01])cylinder(d=7,h=base/2+0.5);
53 | hull()for(t=[-slide/2,slide/2])
54 | translate([t,t,0.48+base/2])cylinder(d1=7,d2=3.5,h=2);
55 | }
56 | for(y=[-9,9])hull()
57 | { // Clip
58 | b(-size,y,3.901,1,8+0.2,1);
59 | b(-size-1,y,2.9,1,8+0.2,1);
60 | }
61 | translate([-1,size-5,-0.01])
62 | cube([2,6,1]); // Resistor to ground on antenna
63 | }
64 | }
65 |
66 | module top()
67 | {
68 | difference()
69 | {
70 | hull()for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0])
71 | {
72 | translate([0,0,chamfer])
73 | cylinder(r=corner+thick,h=led+cover+pcb+4.9-chamfer-(base>0?0:chamfer));
74 | cylinder(r=corner+thick-chamfer,h=led+cover+pcb+4.9);
75 | }
76 | translate([0,0,led+cover])
77 | hull()
78 | {
79 | for(x=[corner-size,size-corner])for(y=[corner-size,size-corner])translate([x,y,0])cylinder(r=corner+0.2,h=pcb+4.9+1);
80 | }
81 | // LEDs
82 | for(y=[12,6,0])
83 | {
84 | // New reverse LED
85 | translate([12,y,0.2])cylinder(d=1.4,h=2+led);
86 | // older surface LED
87 | *b(12,y,-0.01,1.4,1.6,1);
88 | *b(12,y,cover+led-0.3,1.8,4.6,1);
89 | }
90 | if(spox||raspox)b(0,-8.9,cover+0.7,10,2.5,1);
91 | if(tamperth)b(-11.5,-3.25,cover+0.5,7.5,2.5,1);
92 | if(tamperth)b(-11.5,+3.25,cover+0.5,7.5,2.5,1);
93 | if(bell)b(12,-6,cover+0.5,2.54,2.54*2,1);
94 | if(raspox)b(0,-8.9-6.6+7.9-20,led+cover+pcb+1,4,40,4); // cable
95 | }
96 | for(t=[-12,12])translate([t,-t,0])cylinder(d=3,h=led+cover+pcb);
97 | for(y=[-9,9])hull()
98 | { // Clip
99 | b(-size,y,led+cover+pcb+3.9,1,8,1);
100 | b(-size-1,y,led+cover+pcb+3.9-1,1,8,1);
101 | }
102 | }
103 |
104 |
105 | translate([0,0,4.9+base])rotate([180,0,0])base();
106 | translate([45+thick+base,0,0])top();
107 |
108 |
--------------------------------------------------------------------------------
/PCB/Square/production/bom.csv:
--------------------------------------------------------------------------------
1 | Designator,Footprint,Quantity,Value,LCSC Part #
2 | "C1, C2",C_0603,2,160pF,
3 | "C10, C13, C15",C_0603,3,4.7uF,
4 | "C11, C12, C14, C18, C7, C9",C_0603,6,100nF,
5 | "C16, C17, C3, C4",C_0603,4,22pF,
6 | C19,C_0603,1,33pF,
7 | "C5, C6",C_0603,2,220pF,
8 | C8,C_0603,1,1nF,
9 | D1,STP_156120xx7530,1,G,
10 | D2,STP_156120xx7530,1,A,
11 | D3,STP_156120xx7530,1,R,
12 | "D4, D5, D6",SOT-363_SC-70-6,3,BAV99S,
13 | "L1, L2",L_1206_1008,2,560nH,
14 | "R1, R3",R_0603_,2,0R,
15 | "R10, R12, R13, R14, R8, R9",R_0603,6,100R,
16 | "R11, R15, R6",R_0603,3,10K,
17 | R2,R_0805_,1,0R,
18 | R4,R_0603,1,2K7 1%,
19 | R5,R_0603,1,1K 1%,
20 | R7,R_0603,1,20K,
21 | SW1,ESE13,1,ESE13V01D,
22 | U1,QFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm,1,PN532,
23 | Y1,Crystal-3.2x2.5,1,27.12MHz,
24 |
--------------------------------------------------------------------------------
/PCB/Square/production/designators.csv:
--------------------------------------------------------------------------------
1 | A1:1
2 | AJK1:1
3 | C1:1
4 | C10:1
5 | C11:1
6 | C12:1
7 | C13:1
8 | C14:1
9 | C15:1
10 | C16:1
11 | C17:1
12 | C18:1
13 | C19:1
14 | C2:1
15 | C3:1
16 | C4:1
17 | C5:1
18 | C6:1
19 | C7:1
20 | C8:1
21 | C9:1
22 | D1:1
23 | D2:1
24 | D3:1
25 | D4:1
26 | D5:1
27 | D6:1
28 | H1:1
29 | H2:1
30 | J1:1
31 | J2:1
32 | JP1:1
33 | L1:1
34 | L2:1
35 | R1:1
36 | R10:1
37 | R11:1
38 | R12:1
39 | R13:1
40 | R14:1
41 | R15:1
42 | R2:1
43 | R3:1
44 | R4:1
45 | R5:1
46 | R6:1
47 | R7:1
48 | R8:1
49 | R9:1
50 | SW1:1
51 | TP1:1
52 | U1:1
53 | U2:1
54 | U3:1
55 | Y1:1
56 |
--------------------------------------------------------------------------------
/PCB/Square/production/gerber.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PCB/Square/production/gerber.zip
--------------------------------------------------------------------------------
/PCB/Square/production/netlist.ipc:
--------------------------------------------------------------------------------
1 | P CODE 00
2 | P UNITS CUST 0
3 | P arrayDim N
4 | 317GND VIA MD0157PA00X+041102Y-040669X0315Y0000R000S3
5 | 317GND VIA MD0157PA00X+043680Y-035812X0315Y0000R000S3
6 | 317GND VIA MD0157PA00X+036614Y-040777X0315Y0000R000S3
7 | 317GND VIA MD0157PA00X+035945Y-040787X0315Y0000R000S3
8 | 317GND VIA MD0157PA00X+041541Y-039702X0315Y0000R000S3
9 | 317GND VIA MD0157PA00X+039370Y-036545X0315Y0000R000S3
10 | 317GND VIA MD0157PA00X+042913Y-042232X0315Y0000R000S3
11 | 317GND VIA MD0157PA00X+039370Y-039386X0315Y0000R000S3
12 | 317GND VIA MD0157PA00X+043701Y-040591X0315Y0000R000S3
13 | 317GND VIA MD0157PA00X+043547Y-038039X0315Y0000R000S3
14 | 317GND VIA MD0157PA00X+039764Y-039780X0315Y0000R000S3
15 | 317GND VIA MD0157PA00X+038210Y-040700X0315Y0000R000S3
16 | 317GND VIA MD0157PA00X+038976Y-039764X0315Y0000R000S3
17 | 317GND VIA MD0157PA00X+041801Y-037598X0315Y0000R000S3
18 | 317GND VIA MD0157PA00X+042913Y-040542X0315Y0000R000S3
19 | 317GND VIA MD0157PA00X+042913Y-041565X0315Y0000R000S3
20 | 317GND VIA MD0157PA00X+039764Y-038976X0315Y0000R000S3
21 | 317GND VIA MD0157PA00X+038976Y-038976X0315Y0000R000S3
22 | 317GND VIA MD0157PA00X+037776Y-038652X0315Y0000R000S3
23 | 317+3V3 VIA MD0157PA00X+038327Y-037480X0315Y0000R000S3
24 | 317+3V3 VIA MD0157PA00X+042165Y-037953X0315Y0000R000S3
25 | 317+3V3 VIA MD0157PA00X+036299Y-036555X0315Y0000R000S3
26 | 317+3V3 VIA MD0157PA00X+042165Y-040906X0315Y0000R000S3
27 | 317+3V3 VIA MD0157PA00X+042165Y-041693X0315Y0000R000S3
28 | 317+3V3 VIA MD0157PA00X+035984Y-041732X0315Y0000R000S3
29 | 317+3V3 VIA MD0157PA00X+039182Y-037276X0315Y0000R000S3
30 | 317+5V VIA MD0157PA00X+042913Y-037156X0315Y0000R000S3
31 | 317+5V VIA MD0157PA00X+041437Y-037835X0315Y0000R000S3
32 | 317+5V VIA MD0157PA00X+041437Y-037156X0315Y0000R000S3
33 | 317NET-(D1-PAD2) VIA MD0157PA00X+044295Y-038291X0315Y0000R000S3
34 | 317NET-(D1-PAD2) VIA MD0157PA00X+043573Y-039783X0315Y0000R000S3
35 | 317NET-(D2-PAD2) VIA MD0157PA00X+044096Y-035812X0315Y0000R000S3
36 | 317NET-(D2-PAD2) VIA MD0157PA00X+043921Y-038165X0315Y0000R000S3
37 | 317NET-(D3-PAD2) VIA MD0157PA00X+042953Y-039142X0315Y0000R000S3
38 | 317NET-(D3-PAD2) VIA MD0157PA00X+043263Y-035812X0315Y0000R000S3
39 | 317NET-(C9-PAD1) VIA MD0157PA00X+037087Y-036890X0315Y0000R000S3
40 | 317NET-(C9-PAD1) VIA MD0157PA00X+037962Y-037766X0315Y0000R000S3
41 | 317NET-(J2-PAD4) VIA MD0157PA00X+041693Y-042126X0315Y0000R000S3
42 | 327NET-(C16-PAD1) Y1 -1 A01X+036614Y-038917X0512Y0413R270S2
43 | 327GND Y1 -2 A01X+036614Y-039823X0512Y0413R270S2
44 | 327NET-(C17-PAD1) Y1 -3 A01X+037303Y-039823X0512Y0413R270S2
45 | 327GND Y1 -4 A01X+037303Y-038917X0512Y0413R270S2
46 | 367N/C H2 D1260UA00X+034646Y-034646X1260Y0000R000S0
47 | 367N/C H1 D1260UA00X+044094Y-044094X1260Y0000R000S0
48 | 317N/C D2 D0709PA00X+044094Y-037008X0717Y0000R270S0
49 | 327GND D2 -1 A01X+044094Y-037648X0197Y0197R270S2
50 | 327NET-(D2-PAD2) D2 -2 A01X+044094Y-036368X0197Y0197R090S2
51 | 317N/C D3 D0709PA00X+044094Y-034646X0717Y0000R270S0
52 | 327GND D3 -1 A01X+044094Y-035285X0197Y0197R270S2
53 | 327NET-(D3-PAD2) D3 -2 A01X+044094Y-034006X0197Y0197R090S2
54 | 327N/C SW1 A01X+035898Y-040197X0276Y0472R270S2
55 | 327N/C SW1 A01X+034508Y-040197X0276Y0472R270S2
56 | 327GND SW1 -1 A01X+034496Y-041378X0276Y0472R270S2
57 | 327NET-(R11-PAD2) SW1 -2 A01X+035898Y-041378X0276Y0472R270S2
58 | 317N/C D1 D0709PA00X+044094Y-039370X0717Y0000R270S0
59 | 327GND D1 -1 A01X+044094Y-040010X0197Y0197R270S2
60 | 327NET-(D1-PAD2) D1 -2 A01X+044094Y-038730X0197Y0197R090S2
61 | 327+3V3 C7 -1 A01X+039606Y-037480X0315Y0374R000S2
62 | 327GND C7 -2 A01X+040217Y-037480X0315Y0374R000S2
63 | 327NET-(C3-PAD1) C3 -1 A01X+040866Y-034764X0315Y0374R270S2
64 | 327NET-(A1-PAD1) C3 -2 A01X+040866Y-034154X0315Y0374R270S2
65 | 327GND C5 -1 A01X+039734Y-034754X0315Y0374R000S2
66 | 327NET-(C3-PAD1) C5 -2 A01X+040344Y-034754X0315Y0374R000S2
67 | 327NET-(R6-PAD1) R6 -1 A01X+042589Y-037717X0315Y0374R000S2
68 | 327+5V R6 -2 A01X+043238Y-037717X0315Y0374R000S2
69 | 327NET-(C8-PAD2) R4 -1 A01X+036644Y-034754X0315Y0374R000S2
70 | 327NET-(C4-PAD2) R4 -2 A01X+037293Y-034754X0315Y0374R000S2
71 | 327+3V3 C13 -1 A01X+041791Y-038907X0315Y0374R090S2
72 | 327GND C13 -2 A01X+041791Y-039518X0315Y0374R090S2
73 | 327+5V C14 -1 A01X+041191Y-038307X0315Y0374R000S2
74 | 327GND C14 -2 A01X+041801Y-038307X0315Y0374R000S2
75 | 327NET-(C9-PAD1) C9 -1 A01X+036654Y-037303X0315Y0374R000S2
76 | 327GND C9 -2 A01X+037264Y-037303X0315Y0374R000S2
77 | 327NET-(C16-PAD1) C16 -1 A01X+036654Y-038386X0315Y0374R000S2
78 | 327GND C16 -2 A01X+037264Y-038386X0315Y0374R000S2
79 | 327NET-(R9-PAD1) R9 -1 A01X+042589Y-039488X0315Y0374R000S2
80 | 327NET-(D2-PAD2) R9 -2 A01X+043238Y-039488X0315Y0374R000S2
81 | 327NET-(R8-PAD1) R8 -1 A01X+042589Y-040079X0315Y0374R000S2
82 | 327NET-(D1-PAD2) R8 -2 A01X+043238Y-040079X0315Y0374R000S2
83 | 327+3V3 R11 -1 A01X+039094Y-041722X0315Y0374R270S2
84 | 327NET-(R11-PAD2) R11 -2 A01X+039094Y-041073X0315Y0374R270S2
85 | 327GND U1 -1 A01X+040256Y-038228X0276Y0098R090S2
86 | 327CTED-(U1-PAD2) U1 -2 A01X+040059Y-038228X0276Y0098R090S2
87 | 327GND U1 -3 A01X+039862Y-038228X0276Y0098R090S2
88 | 327NET-(L1-PAD1) U1 -4 A01X+039665Y-038228X0276Y0098R090S2
89 | 327+3V3 U1 -5 A01X+039469Y-038228X0276Y0098R090S2
90 | 327NET-(L2-PAD2) U1 -6 A01X+039272Y-038228X0276Y0098R090S2
91 | 327GND U1 -7 A01X+039075Y-038228X0276Y0098R090S2
92 | 327+3V3 U1 -8 A01X+038878Y-038228X0276Y0098R090S2
93 | 327NET-(C9-PAD1) U1 -9 A01X+038681Y-038228X0276Y0098R090S2
94 | 327NET-(C8-PAD1) U1 -10 A01X+038484Y-038228X0276Y0098R090S2
95 | 327GND U1 -11 A01X+038228Y-038484X0098Y0276R090S2
96 | 327TED-(U1-PAD12) U1 -12 A01X+038228Y-038681X0098Y0276R090S2
97 | 327TED-(U1-PAD13) U1 -13 A01X+038228Y-038878X0098Y0276R090S2
98 | 327NET-(C16-PAD1) U1 -14 A01X+038228Y-039075X0098Y0276R090S2
99 | 327NET-(C17-PAD1) U1 -15 A01X+038228Y-039272X0098Y0276R090S2
100 | 327GND U1 -16 A01X+038228Y-039469X0098Y0276R090S2
101 | 327NET-(JP1-PAD2) U1 -17 A01X+038228Y-039665X0098Y0276R090S2
102 | 327GND U1 -18 A01X+038228Y-039862X0098Y0276R090S2
103 | 327TED-(U1-PAD19) U1 -19 A01X+038228Y-040059X0098Y0276R090S2
104 | 327TED-(U1-PAD20) U1 -20 A01X+038228Y-040256X0098Y0276R090S2
105 | 327TED-(U1-PAD21) U1 -21 A01X+038484Y-040512X0276Y0098R090S2
106 | 327TED-(U1-PAD22) U1 -22 A01X+038681Y-040512X0276Y0098R090S2
107 | 327+3V3 U1 -23 A01X+038878Y-040512X0276Y0098R090S2
108 | 327NET-(R11-PAD2) U1 -24 A01X+039075Y-040512X0276Y0098R090S2
109 | 327TED-(U1-PAD25) U1 -25 A01X+039272Y-040512X0276Y0098R090S2
110 | 327TED-(U1-PAD26) U1 -26 A01X+039469Y-040512X0276Y0098R090S2
111 | 327NET-(C19-PAD1) U1 -27 A01X+039665Y-040512X0276Y0098R090S2
112 | 327NET-(D6-PAD6) U1 -28 A01X+039862Y-040512X0276Y0098R090S2
113 | 327TED-(U1-PAD29) U1 -29 A01X+040059Y-040512X0276Y0098R090S2
114 | 327NET-(D4-PAD3) U1 -30 A01X+040256Y-040512X0276Y0098R090S2
115 | 327NET-(R8-PAD1) U1 -31 A01X+040512Y-040256X0098Y0276R090S2
116 | 327NET-(R9-PAD1) U1 -32 A01X+040512Y-040059X0098Y0276R090S2
117 | 327NET-(R10-PAD1) U1 -33 A01X+040512Y-039862X0098Y0276R090S2
118 | 327TED-(U1-PAD34) U1 -34 A01X+040512Y-039665X0098Y0276R090S2
119 | 327TED-(U1-PAD35) U1 -35 A01X+040512Y-039469X0098Y0276R090S2
120 | 327TED-(U1-PAD36) U1 -36 A01X+040512Y-039272X0098Y0276R090S2
121 | 327TED-(U1-PAD37) U1 -37 A01X+040512Y-039075X0098Y0276R090S2
122 | 327NET-(R6-PAD1) U1 -38 A01X+040512Y-038878X0098Y0276R090S2
123 | 327+3V3 U1 -39 A01X+040512Y-038681X0098Y0276R090S2
124 | 327+5V U1 -40 A01X+040512Y-038484X0098Y0276R090S2
125 | 327GND U1 -41 A01X+039370Y-039370X1732Y1732R090S2
126 | 327NET-(C17-PAD1) C17 -1 A01X+037264Y-040354X0315Y0374R180S2
127 | 327GND C17 -2 A01X+036654Y-040354X0315Y0374R180S2
128 | 317GND J1 -1 D0394PA00X+044094Y-042232X0669Y0669R180S0
129 | 317NET-(J1-PAD2) J1 -2 D0394PA00X+044094Y-041232X0669Y0669R180S0
130 | 327+3V3 C12 -1 A01X+039134Y-036949X0315Y0374R180S2
131 | 327GND C12 -2 A01X+038524Y-036949X0315Y0374R180S2
132 | 327NET-(C8-PAD1) R5 -1 A01X+036654Y-036230X0315Y0374R090S2
133 | 327NET-(C9-PAD1) R5 -2 A01X+036654Y-036880X0315Y0374R090S2
134 | 327NET-(R6-PAD1) R7 -1 A01X+042589Y-038307X0315Y0374R000S2
135 | 327GND R7 -2 A01X+043238Y-038307X0315Y0374R000S2
136 | 327NET-(R10-PAD1) R10 -1 A01X+042589Y-038898X0315Y0374R000S2
137 | 327NET-(D3-PAD2) R10 -2 A01X+043238Y-038898X0315Y0374R000S2
138 | 327+3V3 C18 -1 A01X+038465Y-041703X0315Y0374R270S2
139 | 327GND C18 -2 A01X+038465Y-041093X0315Y0374R270S2
140 | 327+3V3 C11 -1 A01X+041201Y-038907X0315Y0374R090S2
141 | 327GND C11 -2 A01X+041201Y-039518X0315Y0374R090S2
142 | 327NET-(C8-PAD1) C8 -1 A01X+036654Y-035817X0315Y0374R270S2
143 | 327NET-(C8-PAD2) C8 -2 A01X+036654Y-035207X0315Y0374R270S2
144 | 317GND J2 -1 D0335PA00X+037894Y-042874X0669Y0728R000S0
145 | 317+5V J2 -2 D0335PA00X+038878Y-042874X0669Y0728R000S0
146 | 317NET-(J2-PAD3) J2 -3 D0335PA00X+039862Y-042874X0669Y0728R000S0
147 | 317NET-(J2-PAD4) J2 -4 D0335PA00X+040846Y-042874X0669Y0728R000S0
148 | 327+3V3 C10 -1 A01X+039606Y-036949X0315Y0374R000S2
149 | 327GND C10 -2 A01X+040217Y-036949X0315Y0374R000S2
150 | 327NET-(A1-PAD1) C1 -1 A01X+040344Y-034134X0315Y0374R180S2
151 | 327GND C1 -2 A01X+039734Y-034134X0315Y0374R180S2
152 | 327GND C6 -1 A01X+039006Y-034754X0315Y0374R180S2
153 | 327NET-(C4-PAD2) C6 -2 A01X+038396Y-034754X0315Y0374R180S2
154 | 327+3V3 R15 -1 A01X+041575Y-041722X0315Y0374R270S2
155 | 327NET-(D4-PAD3) R15 -2 A01X+041575Y-041073X0315Y0374R270S2
156 | 317NET-(L1-PAD1) TP1 -1 D0315PA00X+039862Y-036378X0472Y0000R180S0
157 | 317NET-(L2-PAD2) TP1 -2 D0315PA00X+038878Y-036378X0472Y0000R180S0
158 | 327GND JP1 -1 A01X+036752Y-041496X0394Y0197R000S2
159 | 327NET-(JP1-PAD2) JP1 -2 A01X+037264Y-041496X0394Y0591R000S2
160 | 327+3V3 JP1 -3 A01X+037776Y-041496X0394Y0197R000S2
161 | 327NET-(J2-PAD3) R13 -1 A01X+039695Y-041693X0315Y0374R000S2
162 | 327NET-(D6-PAD6) R13 -2 A01X+040344Y-041693X0315Y0374R000S2
163 | 327+3V3 C15 -1 A01X+036654Y-037835X0315Y0374R000S2
164 | 327GND C15 -2 A01X+037264Y-037835X0315Y0374R000S2
165 | 327NET-(J2-PAD4) R14 -1 A01X+040344Y-041102X0315Y0374R180S2
166 | 327NET-(C19-PAD1) R14 -2 A01X+039695Y-041102X0315Y0374R180S2
167 | 327NET-(L1-PAD1) L1 -1 A01X+040371Y-036105X0276Y0984R315S2
168 | 327NET-(L1-PAD1) L1 -1 A01X+040260Y-036217X0402Y0760R315S2
169 | 327NET-(C3-PAD1) L1 -2 A01X+041039Y-035437X0402Y0760R315S2
170 | 327NET-(C3-PAD1) L1 -2 A01X+040928Y-035548X0276Y0984R315S2
171 | 327NET-(C4-PAD2) L2 -1 A01X+037701Y-035437X0402Y0760R045S2
172 | 327NET-(C4-PAD2) L2 -1 A01X+037812Y-035548X0276Y0984R045S2
173 | 327NET-(L2-PAD2) L2 -2 A01X+038369Y-036105X0276Y0984R045S2
174 | 327NET-(L2-PAD2) L2 -2 A01X+038480Y-036217X0402Y0760R045S2
175 | 327NET-(A1-PAD3) C4 -1 A01X+037874Y-034154X0315Y0374R090S2
176 | 327NET-(C4-PAD2) C4 -2 A01X+037874Y-034764X0315Y0374R090S2
177 | 327NET-(D4-PAD3) R12 -1 A01X+040945Y-041073X0315Y0374R090S2
178 | 327NET-(J1-PAD2) R12 -2 A01X+040945Y-041722X0315Y0374R090S2
179 | 327GND D5 -1 A01X+042539Y-036713X0256Y0157R000S2
180 | 327+3V3 D5 -2 A01X+042539Y-036969X0256Y0157R000S2
181 | 327NET-(D3-PAD2) D5 -3 A01X+042539Y-037224X0256Y0157R000S2
182 | 327GND D5 -4 A01X+043287Y-037224X0256Y0157R000S2
183 | 327+3V3 D5 -5 A01X+043287Y-036969X0256Y0157R000S2
184 | 327NET-(D2-PAD2) D5 -6 A01X+043287Y-036713X0256Y0157R000S2
185 | 327N/C U2 A01X+035197Y-042992X0079Y0236R000S3
186 | 327N/C U2 A01X+034567Y-043425X0079Y0157R000S3
187 | 327N/C U2 A01X+034409Y-042953X0079Y0472R000S3
188 | 327N/C U2 A01X+035236Y-044173X0157Y0079R000S3
189 | 327N/C U2 A01X+035039Y-043780X0079Y0236R000S3
190 | 327N/C U2 A01X+035748Y-044331X0551Y0079R000S3
191 | 327N/C U2 A01X+035748Y-044094X0236Y0236R000S3
192 | 327N/C U2 A01X+035984Y-043268X0079Y0315R000S3
193 | 327N/C U2 A01X+035669Y-043268X0079Y0157R000S3
194 | 327N/C U2 A01X+035748Y-043622X0079Y0079R000S3
195 | 327N/C U2 A01X+035118Y-043307X0236Y0079R000S3
196 | 327N/C U2 A01X+035039Y-043150X0079Y0236R000S3
197 | 327N/C U2 A01X+034646Y-044331X0551Y0079R000S3
198 | 327N/C U2 A01X+035118Y-042835X0079Y0079R000S3
199 | 327N/C U2 A01X+035906Y-042835X0079Y0079R000S3
200 | 327N/C U2 A01X+035669Y-043543X0079Y0079R000S3
201 | 327N/C U2 A01X+035433Y-043701X0236Y0079R000S3
202 | 327N/C U2 A01X+035669Y-043071X0079Y0079R000S3
203 | 327N/C U2 A01X+034488Y-043701X0236Y0079R000S3
204 | 327N/C U2 A01X+035354Y-043898X0079Y0157R000S3
205 | 327N/C U2 A01X+035197Y-043740X0079Y0472R000S3
206 | 327N/C U2 A01X+035591Y-043150X0079Y0236R000S3
207 | 327N/C U2 A01X+034606Y-043543X0157Y0079R000S3
208 | 327N/C U2 A01X+035433Y-043465X0079Y0079R000S3
209 | 327N/C U2 A01X+034882Y-044055X0079Y0472R000S3
210 | 327N/C U2 A01X+035315Y-044094X0157Y0079R000S3
211 | 327N/C U2 A01X+035512Y-043071X0079Y0079R000S3
212 | 327N/C U2 A01X+034646Y-042756X0394Y0079R000S3
213 | 327N/C U2 A01X+035984Y-042835X0079Y0236R000S3
214 | 327N/C U2 A01X+035512Y-043504X0079Y0315R000S3
215 | 327N/C U2 A01X+035591Y-043425X0079Y0157R000S3
216 | 327N/C U2 A01X+034449Y-043543X0157Y0236R000S3
217 | 327N/C U2 A01X+035394Y-043307X0157Y0079R000S3
218 | 327N/C U2 A01X+035591Y-042913X0079Y0079R000S3
219 | 327N/C U2 A01X+035276Y-042835X0079Y0236R000S3
220 | 327N/C U2 A01X+035315Y-043228X0157Y0079R000S3
221 | 327N/C U2 A01X+034646Y-044094X0236Y0236R000S3
222 | 327N/C U2 A01X+034882Y-043386X0079Y0079R000S3
223 | 327N/C U2 A01X+035984Y-044055X0079Y0472R000S3
224 | 327N/C U2 A01X+035118Y-044252X0079Y0079R000S3
225 | 327N/C U2 A01X+035512Y-044055X0079Y0472R000S3
226 | 327N/C U2 A01X+034646Y-043228X0551Y0079R000S3
227 | 327N/C U2 A01X+035945Y-043622X0157Y0079R000S3
228 | 327N/C U2 A01X+035039Y-044173X0079Y0079R000S3
229 | 327N/C U2 A01X+035354Y-043504X0079Y0157R000S3
230 | 327N/C U2 A01X+035827Y-043071X0079Y0079R000S3
231 | 327N/C U2 A01X+034843Y-043701X0315Y0079R000S3
232 | 327N/C U2 A01X+035748Y-042795X0079Y0157R000S3
233 | 327N/C U2 A01X+035276Y-043150X0079Y0079R000S3
234 | 327N/C U2 A01X+035906Y-042992X0079Y0079R000S3
235 | 327N/C U2 A01X+034724Y-043425X0079Y0157R000S3
236 | 327N/C U2 A01X+035118Y-043150X0079Y0079R000S3
237 | 327N/C U2 A01X+035118Y-044016X0079Y0236R000S3
238 | 327N/C U2 A01X+034882Y-042953X0079Y0472R000S3
239 | 327N/C U2 A01X+034646Y-042992X0236Y0236R000S3
240 | 327N/C U2 A01X+035354Y-042795X0079Y0157R000S3
241 | 327N/C U2 A01X+035748Y-043858X0394Y0079R000S3
242 | 327N/C U2 A01X+034882Y-043543X0079Y0079R000S3
243 | 327N/C U2 A01X+035039Y-043465X0079Y0079R000S3
244 | 327N/C U2 A01X+034961Y-043504X0079Y0315R000S3
245 | 327N/C U2 A01X+035276Y-043780X0079Y0079R000S3
246 | 327N/C U2 A01X+035827Y-043661X0079Y0157R000S3
247 | 327N/C U2 A01X+035276Y-043622X0079Y0079R000S3
248 | 327N/C U2 A01X+035433Y-043071X0079Y0236R000S3
249 | 327N/C U2 A01X+034409Y-044055X0079Y0472R000S3
250 | 327N/C U2 A01X+035118Y-043622X0079Y0079R000S3
251 | 327N/C U2 A01X+035197Y-043386X0236Y0079R000S3
252 | 327N/C U2 A01X+035197Y-044331X0079Y0079R000S3
253 | 327N/C U2 A01X+035591Y-042756X0079Y0079R000S3
254 | 327N/C U2 A01X+035039Y-042835X0079Y0236R000S3
255 | 327N/C U2 A01X+035354Y-044291X0079Y0157R000S3
256 | 327N/C U2 A01X+034646Y-043858X0394Y0079R000S3
257 | 327N/C U2 A01X+035787Y-043228X0157Y0079R000S3
258 | 327NET-(C19-PAD1) C19 -1 A01X+042608Y-042598X0315Y0374R000S2
259 | 327GND C19 -2 A01X+043219Y-042598X0315Y0374R000S2
260 | 327GND D4 -1 A01X+042539Y-040571X0256Y0157R000S2
261 | 327+3V3 D4 -2 A01X+042539Y-040827X0256Y0157R000S2
262 | 327NET-(D4-PAD3) D4 -3 A01X+042539Y-041083X0256Y0157R000S2
263 | 327GND D4 -4 A01X+043287Y-041083X0256Y0157R000S2
264 | 327+3V3 D4 -5 A01X+043287Y-040827X0256Y0157R000S2
265 | 327NET-(D1-PAD2) D4 -6 A01X+043287Y-040571X0256Y0157R000S2
266 | 327GND D6 -1 A01X+043287Y-042106X0256Y0157R180S2
267 | 327+3V3 D6 -2 A01X+043287Y-041850X0256Y0157R180S2
268 | 327NET-(C19-PAD1) D6 -3 A01X+043287Y-041594X0256Y0157R180S2
269 | 327GND D6 -4 A01X+042539Y-041594X0256Y0157R180S2
270 | 327+3V3 D6 -5 A01X+042539Y-041850X0256Y0157R180S2
271 | 327NET-(D6-PAD6) D6 -6 A01X+042539Y-042106X0256Y0157R180S2
272 | 327N/C A1 A01X+039370Y-031890X0197Y0591R090S2
273 | 317N/C A1 D0098PA00X+039764Y-031890X0236Y0000R090S3
274 | 317N/C A1 D0098PA00X+038976Y-031890X0236Y0000R090S3
275 | 327N/C A1 A01X+038189Y-032677X0197Y0197R000S3
276 | 327N/C A1 A02X+039370Y-031890X0591Y0197R000S3
277 | 317N/C A1 D0098PA00X+038189Y-032677X0236Y0000R090S3
278 | 327N/C A1 A01X+039370Y-031890X0591Y0197R000S3
279 | 327N/C A1 A01X+040157Y-032736X0315Y0374R090S2
280 | 327N/C A1 A01X+038583Y-032736X0315Y0374R090S2
281 | 327NET-(A1-PAD1) A1 -1 A01X+040157Y-033406X0315Y0374R090S2
282 | 327GND A1 -2 A01X+039370Y-032677X0197Y0591R090S2
283 | 327NET-(A1-PAD3) A1 -3 A01X+038583Y-033406X0315Y0374R090S2
284 | 327GND C2 -1 A01X+039006Y-034134X0315Y0374R180S2
285 | 327NET-(A1-PAD3) C2 -2 A01X+038396Y-034134X0315Y0374R180S2
286 | 327N/C U3 A02X+035748Y-043228X0551Y0079R180S3
287 | 327N/C U3 A02X+034882Y-043071X0079Y0079R180S3
288 | 327N/C U3 A02X+034803Y-043425X0079Y0157R180S3
289 | 327N/C U3 A02X+034409Y-043268X0079Y0315R180S3
290 | 327N/C U3 A02X+035118Y-043780X0079Y0079R180S3
291 | 327N/C U3 A02X+035039Y-043504X0079Y0157R180S3
292 | 327N/C U3 A02X+034803Y-043150X0079Y0236R180S3
293 | 327N/C U3 A02X+034488Y-042835X0079Y0079R180S3
294 | 327N/C U3 A02X+035787Y-043543X0157Y0079R180S3
295 | 327N/C U3 A02X+035551Y-043701X0315Y0079R180S3
296 | 327N/C U3 A02X+035512Y-043543X0079Y0079R180S3
297 | 327N/C U3 A02X+035433Y-043504X0079Y0315R180S3
298 | 327N/C U3 A02X+034646Y-043622X0079Y0079R180S3
299 | 327N/C U3 A02X+035079Y-043228X0157Y0079R180S3
300 | 327N/C U3 A02X+034606Y-043228X0157Y0079R180S3
301 | 327N/C U3 A02X+035945Y-043543X0157Y0236R180S3
302 | 327N/C U3 A02X+035984Y-042953X0079Y0472R180S3
303 | 327N/C U3 A02X+035354Y-042835X0079Y0236R180S3
304 | 327N/C U3 A02X+035906Y-043701X0236Y0079R180S3
305 | 327N/C U3 A02X+034882Y-044055X0079Y0472R180S3
306 | 327N/C U3 A02X+034409Y-042835X0079Y0236R180S3
307 | 327N/C U3 A02X+035354Y-044173X0079Y0079R180S3
308 | 327N/C U3 A02X+035197Y-043740X0079Y0472R180S3
309 | 327N/C U3 A02X+035276Y-043622X0079Y0079R180S3
310 | 327N/C U3 A02X+035276Y-042835X0079Y0079R180S3
311 | 327N/C U3 A02X+034882Y-043504X0079Y0315R180S3
312 | 327N/C U3 A02X+035000Y-043307X0157Y0079R180S3
313 | 327N/C U3 A02X+034961Y-043465X0079Y0079R180S3
314 | 327N/C U3 A02X+035118Y-042835X0079Y0236R180S3
315 | 327N/C U3 A02X+035197Y-044331X0079Y0079R180S3
316 | 327N/C U3 A02X+035748Y-042756X0394Y0079R180S3
317 | 327N/C U3 A02X+034409Y-044055X0079Y0472R180S3
318 | 327N/C U3 A02X+035512Y-043386X0079Y0079R180S3
319 | 327N/C U3 A02X+035354Y-043465X0079Y0079R180S3
320 | 327N/C U3 A02X+035079Y-044094X0157Y0079R180S3
321 | 327N/C U3 A02X+035039Y-043898X0079Y0157R180S3
322 | 327N/C U3 A02X+035748Y-042992X0236Y0236R180S3
323 | 327N/C U3 A02X+034646Y-044094X0236Y0236R180S3
324 | 327N/C U3 A02X+035197Y-042992X0079Y0236R180S3
325 | 327N/C U3 A02X+034961Y-043071X0079Y0236R180S3
326 | 327N/C U3 A02X+035276Y-043307X0236Y0079R180S3
327 | 327N/C U3 A02X+034567Y-043661X0079Y0157R180S3
328 | 327N/C U3 A02X+035827Y-043425X0079Y0157R180S3
329 | 327N/C U3 A02X+034646Y-043858X0394Y0079R180S3
330 | 327N/C U3 A02X+034724Y-043543X0079Y0079R180S3
331 | 327N/C U3 A02X+035197Y-043386X0236Y0079R180S3
332 | 327N/C U3 A02X+035748Y-043858X0394Y0079R180S3
333 | 327N/C U3 A02X+035748Y-044094X0236Y0236R180S3
334 | 327N/C U3 A02X+034488Y-042992X0079Y0079R180S3
335 | 327N/C U3 A02X+034724Y-043268X0079Y0157R180S3
336 | 327N/C U3 A02X+035276Y-044252X0079Y0079R180S3
337 | 327N/C U3 A02X+035354Y-043150X0079Y0236R180S3
338 | 327N/C U3 A02X+035512Y-044055X0079Y0472R180S3
339 | 327N/C U3 A02X+035669Y-043425X0079Y0157R180S3
340 | 327N/C U3 A02X+035984Y-044055X0079Y0472R180S3
341 | 327N/C U3 A02X+034803Y-042756X0079Y0079R180S3
342 | 327N/C U3 A02X+034803Y-042913X0079Y0079R180S3
343 | 327N/C U3 A02X+035276Y-044016X0079Y0236R180S3
344 | 327N/C U3 A02X+035276Y-043150X0079Y0079R180S3
345 | 327N/C U3 A02X+035039Y-044291X0079Y0157R180S3
346 | 327N/C U3 A02X+035354Y-043780X0079Y0236R180S3
347 | 327N/C U3 A02X+035512Y-042953X0079Y0472R180S3
348 | 327N/C U3 A02X+035118Y-043622X0079Y0079R180S3
349 | 327N/C U3 A02X+034724Y-043071X0079Y0079R180S3
350 | 327N/C U3 A02X+035748Y-044331X0551Y0079R180S3
351 | 327N/C U3 A02X+035157Y-044173X0157Y0079R180S3
352 | 327N/C U3 A02X+035039Y-042795X0079Y0157R180S3
353 | 327N/C U3 A02X+034961Y-043701X0236Y0079R180S3
354 | 327N/C U3 A02X+034567Y-043071X0079Y0079R180S3
355 | 327N/C U3 A02X+035118Y-043150X0079Y0079R180S3
356 | 327N/C U3 A02X+034646Y-044331X0551Y0079R180S3
357 | 327N/C U3 A02X+034449Y-043622X0157Y0079R180S3
358 | 327N/C U3 A02X+034646Y-042795X0079Y0157R180S3
359 | 999
360 |
--------------------------------------------------------------------------------
/PCB/Square/production/positions.csv:
--------------------------------------------------------------------------------
1 | Designator,Mid X,Mid Y,Rotation,Layer
2 | AJK1,89.7,-92.2,0.0,top
3 | C1,101.7,-86.7,180.0,top
4 | C10,101.375,-93.85,0.0,top
5 | C11,104.65,-99.6,270.0,top
6 | C12,98.625,-93.85,180.0,top
7 | C13,106.15,-99.6,270.0,top
8 | C14,105.4,-97.3,0.0,top
9 | C15,93.875,-96.1,0.0,top
10 | C16,93.875,-97.5,0.0,top
11 | C17,93.875,-102.5,180.0,top
12 | C18,97.7,-105.15,90.0,top
13 | C19,109.0,-108.2,0.0,top
14 | C2,98.3,-86.7,180.0,top
15 | C3,103.8,-87.525,90.0,top
16 | C4,96.2,-87.525,270.0,top
17 | C5,101.7,-88.275,0.0,top
18 | C6,98.3,-88.275,180.0,top
19 | C7,101.375,-95.2,0.0,top
20 | C8,93.1,-90.2,90.0,top
21 | C9,93.875,-94.75,0.0,top
22 | D1,112.0,-100.0,90.0,top
23 | D2,112.0,-94.0,90.0,top
24 | D3,112.0,-88.0,90.0,top
25 | D4,109.0,-103.7,0.0,top
26 | D5,109.0,-93.9,0.0,top
27 | D6,109.0,-106.3,180.0,top
28 | J1,112.0,-107.27,180.0,top
29 | J2,100.0,-108.9,0.0,top
30 | L1,103.25,-91.0,45.0,top
31 | L2,96.75,-91.0,315.0,top
32 | R1,98.0,-84.0,90.0,top
33 | R10,109.0,-98.8,0.0,top
34 | R11,99.3,-105.15,90.0,top
35 | R12,104.0,-105.15,270.0,top
36 | R13,101.65,-105.9,0.0,top
37 | R14,101.65,-104.4,180.0,top
38 | R15,105.6,-105.15,90.0,top
39 | R2,100.0,-82.0,90.0,top
40 | R3,102.0,-84.0,90.0,top
41 | R4,93.9,-88.275,0.0,top
42 | R5,93.1,-92.85,270.0,top
43 | R6,109.0,-95.8,0.0,top
44 | R7,109.0,-97.3,0.0,top
45 | R8,109.0,-101.8,0.0,top
46 | R9,109.0,-100.3,0.0,top
47 | SW1,89.4,-103.6,90.0,top
48 | TP1,100.0,-92.4,180.0,top
49 | U1,100.0,-100.0,270.0,top
50 | U3,89.4,-110.6,180.0,bottom
51 | Y1,93.875,-100.0,90.0,top
52 |
--------------------------------------------------------------------------------
/PN532.pages:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/revk/ESP32-PN532/9070a610b5cd0a8d9b2308b9559fb926e9a0fb91/PN532.pages
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ESP32-PN532
2 |
3 | PN532 (HSU) library
4 | - Platform: ESP-IDF (e.g. ESP32)
5 | - Can work with DESFireAES library for NXP MIFARE DESFire EV1 cards
6 | - See include file for details of functions
7 |
8 | Includes KiCad PCB design for PN532 based NFC reader board and 3D case designs. Unlike some NFC boards this includes three traffic light LEDs, a tamper switch, and external contacts for a door bell push, all accessable as GPIO over the HSU connection.
9 |
10 | 
11 |
12 | Copyright © 2019-23 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0
13 |
--------------------------------------------------------------------------------
/component.mk:
--------------------------------------------------------------------------------
1 | #
2 | # "main" pseudo-component makefile.
3 | #
4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
5 |
6 |
--------------------------------------------------------------------------------
/idf_component.yml:
--------------------------------------------------------------------------------
1 | ## IDF Component Manager Manifest File
2 | dependencies:
3 | espressif/led_strip: "*"
4 | ## Required IDF version
5 | idf:
6 | version: ">=4.1.0"
7 | # # Put list of dependencies here
8 | # # For components maintained by Espressif:
9 | # component: "~1.0.0"
10 | # # For 3rd party components:
11 | # username/component: ">=1.0.0,<2.0.0"
12 | # username2/component2:
13 | # version: "~1.0.0"
14 | # # For transient dependencies `public` flag can be set.
15 | # # `public` flag doesn't have an effect dependencies of the `main` component.
16 | # # All dependencies of `main` are public by default.
17 | # public: true
18 |
--------------------------------------------------------------------------------
/include/pn532.h:
--------------------------------------------------------------------------------
1 | // PN532 functions
2 | // Copyright © 2019 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0
3 |
4 | #ifndef PN532_H
5 | #define PN532_H
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #define pn532_errs \
15 | p(OK) \
16 | p(NULL) \
17 | p(NOTPENDING) \
18 | p(CMDPENDING) \
19 | p(CMDMISMATCH) \
20 | p(TIMEOUT) \
21 | p(TIMEOUTACK) \
22 | p(BADACK) \
23 | p(NACK) \
24 | p(HEADER) \
25 | p(SHORT) \
26 | p(SPACE) \
27 | p(CHECKSUM) \
28 | p(POSTAMBLE) \
29 | p(STATUS) \
30 | s(0x01,TIMEOUT) \
31 | s(0x02,CRC) \
32 | s(0x03,PARITY) \
33 | s(0x04,BITCOUNT) \
34 | s(0x05,FRAMING) \
35 | s(0x06,COLLISION) \
36 | s(0x07,SPACE) \
37 | s(0x09,OVERFLOW) \
38 | s(0x0A,NOFIELD) \
39 | s(0x0B,PROTOCOL) \
40 | s(0x0D,TEMPERATURE) \
41 | s(0x0E,INTOVERFLOW) \
42 | s(0x10,PARAMETER) \
43 | s(0x12,DEPPROTOCOL) \
44 | s(0x13,DEPFORMAT) \
45 | s(0x14,MIFAREAUTH) \
46 | s(0x23,UIDCHECK) \
47 | s(0x25,DEPSTATE) \
48 | s(0x26,NOTALLOWED) \
49 | s(0x27,NOTACCEPTABLE) \
50 | s(0x29,RELEASED) \
51 | s(0x2A,CARDSWAPPED) \
52 | s(0x2B,DISAPPEARED) \
53 | s(0x2C,MISMATCHID) \
54 | s(0x2D,OVERCURRENT) \
55 | s(0x2E,NADMISSING) \
56 | s(0x2F,MAX) \
57 |
58 | typedef enum {
59 | #define p(n) PN532_ERR_##n,
60 | #define s(v,n) PN532_ERR_STATUS_##n=PN532_ERR_STATUS+v,
61 | pn532_errs
62 | #undef p
63 | #undef s
64 | } pn532_err_t;
65 |
66 | typedef struct pn532_s pn532_t;
67 |
68 | // Functions
69 |
70 | pn532_t *pn532_init(int8_t uart, uint8_t baud, int8_t tx, int8_t rx, uint8_t p3); // Init PN532 (P3 is port 3 output bits in use), baud is speed code 0-8 for 9600-1288000
71 | void *pn532_end(pn532_t * p); // Close and free
72 |
73 | pn532_err_t pn532_lasterr(pn532_t *);
74 | const char *pn532_err_to_name(pn532_err_t);
75 |
76 | // Low level access functions
77 | int pn532_tx(pn532_t *, uint8_t cmd, int, uint8_t *, int, uint8_t *); // Send data to PN532 (up to two blocks) return 0 or negative for error. Starts byte after cmd
78 | int pn532_ready(pn532_t * p); // For async command handling: >0 if response ready, 0 if not, -ve if error (e.g. no response expected)
79 | int pn532_rx(pn532_t *, int, uint8_t *, int, uint8_t *, int ms); // Recv data from PN532, (in to up to two blocks) return total length or -ve for error, checks res=cmd+1 and returns from byte after
80 | uint8_t *pn532_nfcid(pn532_t *, char text[21]); // Get NFCID (first byte is len of following)
81 | uint8_t *pn532_ats(pn532_t *); // Get ATS (first byte is len of following - note, not as received were it is len inc the length byte)
82 |
83 | // Card access function - sends to card starting CMD byte, and receives reply in to same buffer, starting status byte, returns len
84 | int pn532_dx(void *, unsigned int len, uint8_t * data, unsigned int max, const char **errstr);
85 |
86 | // Higher level useful PN532 functions
87 | int pn532_deselect(pn532_t * p, uint8_t n); // Send deselect ID 1 or 2
88 | int pn532_release(pn532_t * p, uint8_t n); // Send release ID 1 or 2
89 | int pn532_write_GPIO(pn532_t * p, uint8_t value); // (P72/P71 in top bits, P35-30 in rest)
90 | int pn532_read_GPIO(pn532_t * p); // P72/P71 in top bits, P35-30 in rest)
91 | int pn532_ILPT_Send(pn532_t * p); // Async InListPassiveTarget - used pn532_ready to check when to do pn532_Cards
92 | int pn532_Cards(pn532_t * p); // How many cards present (does pn532_ILPT_Send if needed)
93 | int pn532_Present(pn532_t * p); // Check if present still
94 |
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/makeloop.c:
--------------------------------------------------------------------------------
1 | /* General spiral track - for PN532 antenna */
2 | /* (c) 2021 Adrian Kennard Andrews & Arnold Ltd */
3 |
4 | #define _GNU_SOURCE
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | int
20 | main (int argc, const char *argv[])
21 | {
22 | const char *name = "PN532-Antenna6";
23 | const char *text = NULL;
24 | double startr = 22.69;
25 | double width = 0.5;
26 | double step = 1.0;
27 | double starta = NAN;
28 | double enda = NAN;
29 | double stepa = 30;
30 | double edge = NAN;
31 | double ring = NAN;
32 | double texth = 3;
33 | double textr = 18.5;
34 | double textt = 0.4;
35 | double screwx = NAN;
36 | double screwy = 0;
37 | double screwz = 1.25;
38 | double zone = 8; // Fill exclude zone starts away from antenna
39 | double zap = 5; // Fill exclusion zone has slots this deep
40 | double spoke = 12; // Exclude spoke angle
41 | double slot = 1; // Exclude slot angle
42 | int outside = 0;
43 | int debug = 0;
44 | poptContext optCon; /* context for parsing command - line options */
45 | {
46 | const struct poptOption optionsTable[] = {
47 | {"name", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &name, 0, "Name"},
48 | {"text", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &text, 0, "Text"},
49 | {"texth", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &texth, 0, "Text height"},
50 | {"startr", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &startr, 0, "Start (outer) radius"},
51 | {"textr", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &textr, 0, "Text radius"},
52 | {"textt", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &textt, 0, "Text thickness"},
53 | {"width", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &width, 0, "Track width"},
54 | {"step", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &step, 0, "Step per turn"},
55 | {"starta", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &starta, 0, "Start angle"},
56 | {"enda", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &enda, 0, "End angle"},
57 | {"stepa", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &stepa, 0, "Step angle"},
58 | {"screwx", 0, POPT_ARG_DOUBLE, &screwx, 0, "Screw X"},
59 | {"screwy", 0, POPT_ARG_DOUBLE, &screwy, 0, "Screw Y"},
60 | {"screwz", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &screwz, 0, "Screw Z"},
61 | {"edge", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &edge, 0, "Edge"},
62 | {"ring", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &ring, 0, "Ring"},
63 | {"zone", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &zone, 0, "Keepout clearance"},
64 | {"zap", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &zap, 0, "Keepout slot length"},
65 | {"spoke", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &spoke, 0, "Keepout slot spacing"},
66 | {"slot", 0, POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &slot, 0, "Keepout slot width"},
67 | {"outside", 0, POPT_ARG_NONE, &outside, 0, "Outside contact"},
68 | {"debug", 'v', POPT_ARG_NONE, &debug, 0, "Debug"},
69 | POPT_AUTOHELP {}
70 | };
71 |
72 | optCon = poptGetContext (NULL, argc, argv, optionsTable, 0);
73 | /* poptSetOtherOptionHelp(optCon, ""); */
74 |
75 | int c;
76 | if ((c = poptGetNextOpt (optCon)) < -1)
77 | errx (1, "%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (c));
78 |
79 | }
80 | if (!outside && isnan (screwx))
81 | screwx = startr * 12 / 23;
82 | if (isnan (starta))
83 | starta = outside ? 7 : 2.4;
84 | if (isnan (enda))
85 | enda = outside ? 722.7 : 713;
86 | if (!outside && !text)
87 | text = "PN532 HSU NFC READER PN532.REVK.UK";
88 | if (!outside && isnan (ring))
89 | ring = 16;
90 |
91 | #define LF "%.2lf"
92 | #define RES 100
93 | double basex = 0,
94 | basey = 0;
95 |
96 | inline double xr (double a, double r)
97 | {
98 | return round ((r * sin (a * M_PI / 180.0) - basex) * RES) / RES;
99 | }
100 | inline double x (double a)
101 | {
102 | double r = startr - step * a / 360;
103 | if (a < 0)
104 | r = startr;
105 | return xr (a, r);
106 | }
107 | inline double yr (double a, double r)
108 | {
109 | return round ((-r * cos (a * M_PI / 180.0) + step / 4 - basey) * RES) / RES;
110 | }
111 | inline double y (double a)
112 | {
113 | double r = startr - step * a / 360;
114 | if (a < 0)
115 | r = startr;
116 | return yr (a, r);
117 | }
118 |
119 | printf ("(footprint \"%s\" (layer \"F.Cu\") (version 20211014) ", name);
120 | printf ("(attr through_hole exclude_from_pos_files exclude_from_bom)");
121 | printf ("(fp_text reference \"Ref**\" (at 0 0) (layer \"F.SilkS\") hide (effects (font (size 1.27 1.27) (thickness 0.15))))");
122 | printf ("(fp_text value \"Val**\" (at 0 0) (layer \"F.SilkS\") hide (effects (font (size 1.27 1.27) (thickness 0.15))))");
123 | if (!isnan (edge) && edge)
124 | printf ("(fp_circle (center 0 0) (end " LF " 0) (layer \"Edge.Cuts\") (width 0.1) (fill none))", edge);
125 | if (!isnan (ring) && ring)
126 | printf ("(fp_circle (center 0 0) (end " LF " 0) (layer \"Dwgs.User\") (width 0.2) (fill none))", ring);
127 | if (text && *text)
128 | {
129 | const char thin[] = ".:'";
130 | double s = texth / (textr - texth / 2) * 0.9,
131 | a = 0;
132 | for (const char *p = text; *p; p++)
133 | a += (strchr (thin, *p) ? s / 2 : s);
134 | a = M_PI - a / 2 + s / 2;
135 | for (const char *p = text; *p; p++)
136 | {
137 | if (strchr (thin, *p))
138 | a -= s / 4;
139 | if (*p != ' ')
140 | printf ("(fp_text user \"%c\" (at " LF " " LF " " LF " unlocked) (layer \"F.SilkS\")(effects (font (size " LF " " LF
141 | ") (thickness " LF "))))", *p, textr * sin (a), -textr * cos (a), -180 * a / M_PI, texth, texth, textt);
142 | if (strchr (thin, *p))
143 | a -= s / 4;
144 | a += s;
145 | }
146 | }
147 | { /* Components */
148 | /* top link */
149 | int d = outside ? -1 : 1;
150 | double dy = y (roundl (enda / 360) * 360) - y (roundl (starta / 360) * 360);
151 | if (dy > 1.5 && dy < 2.5)
152 | { /* 0805 2mm high */
153 | double a = outside ? enda : starta;
154 | double Y = y (a);
155 | double W = x (a) * 2;
156 | // Holes
157 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", W / 2, Y,
158 | width, width, width / 2);
159 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", -W / 2, Y,
160 | width, width, width / 2);
161 | // Join holes
162 | printf ("(pad \"0\" smd rect (at 0 " LF " 0) (size " LF " " LF ") (layers \"F.Cu\" \"B.Cu\"))", Y, W, width);
163 | // Centre tap pad
164 | printf ("(pad \"0\" smd rect (at 0 " LF " 0) (size 1.4 " LF ") (layers \"F.Paste\" \"F.Mask\"))", Y, width);
165 | // Centre dot
166 | Y += d;
167 | printf ("(fp_circle (center 0 " LF ") (end 0.05 " LF ") (layer \"Dwgs.User\") (width 0.12) (fill none))", Y, Y);
168 | // Contact pad
169 | Y += d;
170 | printf ("(pad \"2\" smd rect (at 0 " LF " 0) (size 1.4 " LF ") (layers \"F.Cu\" \"F.Paste\" \"F.Mask\"))", Y, width);
171 | }
172 | /* 0603 1.6 mm high */
173 | double a = outside ? starta : enda;
174 | // Hole
175 | printf ("(pad \"0\" thru_hole circle (at " LF " " LF ") (size " LF " " LF ") (drill " LF ") (layers *.Cu))", x (a), y (a),
176 | width, width, width / 2);
177 | for (int m = -1; m <= 1; m += 2)
178 | {
179 | double X = x (a) + width / 4;
180 | double Y = y (a);
181 | if (outside)
182 | X -= 1 + width;
183 | // Copper
184 | printf ("(pad \"0\" smd rect (at " LF " " LF " 0) (size " LF " " LF ") (layers \"F.Cu\"))",
185 | m * (X + 0.5 + (outside ? width / 2 : 0)), Y, 1 + width / 2, width);
186 | // Mask
187 | X += width / 4;
188 | printf ("(pad \"0\" smd rect (at " LF " " LF " 0) (size 1 " LF ") (layers \"F.Paste\" \"F.Mask\"))", m * (X + 0.5), Y,
189 | width);
190 | // Dot
191 | Y += d * 0.8;
192 | printf ("(fp_circle (center " LF " " LF ") (end " LF " " LF ") (layer \"Dwgs.User\") (width 0.12) (fill none))",
193 | m * (X + 0.5), Y, m * (X + 0.5 + 0.05), Y);
194 | Y += d * 0.8;
195 | printf ("(pad \"%d\" smd rect (at " LF " " LF " 0) (size 1 " LF ") (layers \"F.Cu\" \"F.Paste\" \"F.Mask\"))", m + 2,
196 | m * (X + 0.5), Y, width);
197 | }
198 | if (!isnan (screwx))
199 | {
200 | printf ("(model \"/Users/adrian/Documents/KiCad/3D/653612.stp\" (offset (xyz " LF " " LF " " LF
201 | ")) (scale (xyz 0.58 0.58 0.58)) (rotate (xyz 0 -90 -35)))", screwx, screwy, screwz);
202 | printf ("(model \"/Users/adrian/Documents/KiCad/3D/653612.stp\" (offset (xyz " LF " " LF " " LF
203 | ")) (scale (xyz 0.58 0.58 0.58)) (rotate (xyz 0 -90 -35)))", -screwx, -screwy, screwz);
204 | }
205 | }
206 | void pad (const char *layer, double flip)
207 | {
208 | basex = basey = 0;
209 | printf ("(pad \"0\" smd custom (at " LF " " LF ") (size " LF " " LF
210 | ") (layers \"%s\") (options (clearance outline) (anchor circle)) (primitives ", flip * x (starta), y (starta), width,
211 | width, layer);
212 | basex = x (starta);
213 | basey = y (starta);
214 | void arc (double s, double e)
215 | {
216 | double m = (s + e) / 2;
217 | printf ("(gr_arc (start " LF " " LF ") (mid " LF " " LF ") (end " LF " " LF ") (width " LF "))", flip * x (s), y (s),
218 | flip * x (m), y (m), flip * x (e), y (e), width);
219 | }
220 | double a = 0;
221 | if (starta < 0)
222 | arc (starta, 0);
223 | else if (starta > 0 && starta < stepa)
224 | arc (starta, a = stepa);
225 | for (; a + stepa < enda; a += stepa)
226 | arc (a, a + stepa);
227 | if (a < enda)
228 | arc (a, enda);
229 | printf ("))");
230 | basex = basey = 0;
231 | }
232 | /* the antenna itself */
233 | pad ("F.Cu", -1);
234 | pad ("B.Cu", 1);
235 | if (zone)
236 | {
237 | printf
238 | ("(zone(net 0)(net_name \"0\")(layers \"F&B.Cu\")(hatch edge 0.5)(connect_pads(clearance 0))(min_thickness 0.25)(filled_areas_thickness no)(keepout(tracks allowed)(vias allowed)(pads allowed)(copperpour not_allowed)(footprints allowed))(fill(thermal_gap 0.5)(thermal_bridge_width 0.5))(polygon(pts");
239 | double delta = spoke / 2;
240 | void zy (double a, double r)
241 | {
242 | printf ("(xy " LF " " LF ")", xr (a + delta, r), yr (a + delta, r));
243 | }
244 | zy (0, startr + step * 2 + zone);
245 | for (double a = -slot / 2; a < 360; a += spoke)
246 | {
247 | zy (a, startr + step * 2 + zone);
248 | zy (a, startr + step * 2 + zone + zap);
249 | zy (a + slot, startr + step * 2 + zone + zap);
250 | zy (a + slot, startr + step * 2 + zone);
251 | }
252 | zy (0, startr + step * 2 + zone);
253 | zy (0, startr - zone);
254 | for (double a = -slot / 2; a < 360; a += spoke)
255 | {
256 | zy (-a, startr - zone);
257 | zy (-a, startr - zone - zap);
258 | zy (-a - slot, startr - zone - zap);
259 | zy (-a - slot, startr - zone);
260 | }
261 | zy (0, startr - zone);
262 | printf (")))");
263 | }
264 | printf (")");
265 | poptFreeContext (optCon);
266 | return 0;
267 | }
268 |
--------------------------------------------------------------------------------
/pn532.c:
--------------------------------------------------------------------------------
1 | // PN532 functions
2 | // Copyright © 2019 Adrian Kennard, Andrews & Arnold Ltd. See LICENCE file for details. GPL 3.0
3 | static const char TAG[] = "PN532";
4 |
5 | #include "sdkconfig.h"
6 | #include "pn532.h"
7 | #include "esp_log.h"
8 | #include
9 | #include
10 |
11 | #define HEXLOG ESP_LOG_INFO
12 | #define DXLOG ESP_LOG_INFO
13 | #define MSGLOG ESP_LOG_ERROR
14 | #define RX_BUF 280
15 | #define TX_BUF 280
16 |
17 | struct pn532_s
18 | {
19 | uint8_t uart; // Which UART
20 | volatile uint8_t pending; // Pending response
21 | uint8_t lasterr; // Last error (obviously not for PN532_ERR_NULL)
22 | uint8_t cards; // Cards present (0, 1 or 2)
23 | uint8_t tg; // First card target id (normally 1)
24 | uint16_t sens_res; // From InListPassiveTarget
25 | uint8_t sel_res; // From InListPassiveTarget
26 | uint8_t nfcid[11]; // First card ID last seen (starts with len)
27 | uint8_t ats[30]; // First card ATS last seen (starts with len)
28 | SemaphoreHandle_t mutex; // DX mutex
29 | };
30 |
31 | // Data
32 | static const char *const pn532_err_str[PN532_ERR_STATUS_MAX + 1] = {
33 | #define p(n) [PN532_ERR_##n]="PN532_ERR_"#n,
34 | #define s(v,n) [PN532_ERR_STATUS_##n]="PN532_ERR_STATUS_"#n,
35 | pn532_errs
36 | #undef p
37 | #undef s
38 | };
39 |
40 | pn532_err_t
41 | pn532_lasterr (pn532_t * p)
42 | {
43 | if (!p)
44 | return -PN532_ERR_NULL;
45 | #if 0
46 | if (p->lasterr > PN532_ERR_STATUS)
47 | ESP_LOGI (TAG, "Last err status %02X", p->lasterr - PN532_ERR_STATUS);
48 | else
49 | ESP_LOGI (TAG, "Last err %d", p->lasterr);
50 | #endif
51 | return p->lasterr;
52 | }
53 |
54 | const char *
55 | pn532_err_to_name (pn532_err_t e)
56 | {
57 | if (e < 0)
58 | e = -e;
59 | if (e > PN532_ERR_STATUS_MAX)
60 | return "PN532_ERR_UNKNOWN";
61 | return pn532_err_str[e];
62 | }
63 |
64 | static int
65 | uart_rx (pn532_t * p, uint8_t * buf, uint32_t length, int ms)
66 | { // Low level UART rx with optional logging
67 | if (!p)
68 | return -PN532_ERR_NULL;
69 | ms /= portTICK_PERIOD_MS;
70 | if (ms < 2)
71 | ms = 2; // Ensure some timeout
72 | int l = uart_read_bytes (p->uart, buf, length, ms);
73 | #ifdef CONFIG_PN532_DUMP
74 | if (l > 0)
75 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", buf, l, HEXLOG);
76 | if (l != length)
77 | ESP_LOGI (TAG, "Rx %d/%ld %d*%ldms", l, length, ms, portTICK_PERIOD_MS);
78 | #endif
79 | return l;
80 | }
81 |
82 | static int
83 | uart_tx (pn532_t * p, const uint8_t * src, size_t size)
84 | { // Low level UART tx with optional logging
85 | if (!p)
86 | return -PN532_ERR_NULL;
87 | int l = uart_write_bytes (p->uart, (char *) src, size);
88 | #ifdef CONFIG_PN532_DUMP
89 | if (l > 0)
90 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", src, l, HEXLOG);
91 | if (l != size)
92 | ESP_LOGI (TAG, "Tx %d/%d", l, size);
93 | #endif
94 | return l;
95 | }
96 |
97 | static int
98 | uart_preamble (pn532_t * p, int ms)
99 | { // Wait for preamble
100 | if (!p)
101 | return -PN532_ERR_NULL;
102 | uint8_t last = 0xFF;
103 | while (1)
104 | {
105 | uint8_t c;
106 | int l = uart_rx (p, &c, 1, ms);
107 | if (l < 1)
108 | return l;
109 | if (last == 0x00 && c == 0xFF)
110 | return 2;
111 | last = c;
112 | }
113 | }
114 |
115 | void *
116 | pn532_end (pn532_t * p)
117 | {
118 | if (p)
119 | {
120 | vSemaphoreDelete (p->mutex);
121 | free (p);
122 | }
123 | return NULL;
124 | }
125 |
126 | pn532_t *
127 | pn532_init (int8_t uart, uint8_t baud, int8_t tx, int8_t rx, uint8_t outputs)
128 | { // Init PN532 (baud is 0-8 for 9600-1288000
129 | if (uart < 0 || tx < 0 || rx < 0 || tx == rx)
130 | return NULL;
131 | if (!GPIO_IS_VALID_OUTPUT_GPIO (tx) || !GPIO_IS_VALID_GPIO (rx))
132 | return NULL;
133 | pn532_t *p = malloc (sizeof (*p));
134 | if (!p)
135 | return p;
136 | memset (p, 0, sizeof (*p));
137 | p->uart = uart;
138 | p->mutex = xSemaphoreCreateBinary ();
139 | xSemaphoreGive (p->mutex);
140 | esp_err_t err = 0;
141 | { // Init UART
142 | uart_config_t uart_config = {
143 | .baud_rate = 115200,
144 | .data_bits = UART_DATA_8_BITS,
145 | .parity = UART_PARITY_DISABLE,
146 | .stop_bits = UART_STOP_BITS_1,
147 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
148 | .source_clk = UART_SCLK_DEFAULT,
149 | };
150 | if (!err)
151 | err = uart_param_config (uart, &uart_config);
152 | if (!err)
153 | err = gpio_reset_pin (tx);
154 | if (!err && tx != rx)
155 | err = gpio_reset_pin (rx);
156 | if (!err)
157 | err = uart_set_pin (uart, tx, rx, -1, -1);
158 | if (!err && !uart_is_driver_installed (uart))
159 | {
160 | ESP_LOGI (TAG, "Installing UART driver %d", uart);
161 | err = uart_driver_install (uart, RX_BUF, TX_BUF, 0, NULL, 0);
162 | }
163 | if (err)
164 | {
165 | ESP_LOGE (TAG, "UART fail %s", esp_err_to_name (err));
166 | return pn532_end (p);
167 | }
168 | }
169 | ESP_LOGD (TAG, "UART %d Tx %d Rx %d", uart, tx, rx);
170 | gpio_set_drive_capability (tx, GPIO_DRIVE_CAP_3); // Oomph?
171 | int n;
172 | uint8_t buf[30] = { 0 };
173 | int e = sizeof (buf);
174 | buf[--e] = 0x55; // Idle
175 | buf[--e] = 0x55;
176 | buf[--e] = 0x55;
177 | uart_flush_input (p->uart);
178 | uart_tx (p, buf, sizeof (buf));
179 | uart_wait_tx_done (p->uart, 100 / portTICK_PERIOD_MS);
180 | if (baud != 4 && baud <= 8)
181 | { // Not the default Baud rate, go through the change of Baud rate step by step
182 | if (pn532_tx (p, 0x10, 1, &baud, 0, NULL) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 20) < 0)
183 | {
184 | ESP_LOGE (TAG, "Baud rate change failed %s", pn532_err_to_name (pn532_lasterr (p)));
185 | return pn532_end (p);
186 | }
187 | // We have to send ACK at current Baud rate
188 | uint8_t ack[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00 };
189 | uart_tx (p, ack, sizeof (ack));
190 | uart_wait_tx_done (p->uart, 100 / portTICK_PERIOD_MS);
191 | usleep (10000);
192 | // Change rate
193 | const uint32_t rate[] = { 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1288000 };
194 | uart_config_t uart_config = {
195 | .baud_rate = rate[baud],
196 | .data_bits = UART_DATA_8_BITS,
197 | .parity = UART_PARITY_DISABLE,
198 | .stop_bits = UART_STOP_BITS_1,
199 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
200 | .source_clk = UART_SCLK_DEFAULT,
201 | };
202 | if (!err)
203 | err = uart_param_config (uart, &uart_config);
204 | if (err)
205 | {
206 | ESP_LOGE (TAG, "UART fail %s", esp_err_to_name (err));
207 | return pn532_end (p);
208 | }
209 | ESP_LOGE (TAG, "Baud rate %ld", rate[baud]);
210 | usleep (10000);
211 | }
212 | // Set up PN532 (SAM first as in vLowBat mode)
213 | // SAMConfiguration
214 | n = 0;
215 | buf[n++] = 0x01; // Normal
216 | buf[n++] = 20; // *50ms timeout
217 | buf[n++] = 0x00; // Not use IRQ
218 | if (pn532_tx (p, 0x14, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
219 | { // Again
220 | uart_rx (p, buf, sizeof (buf), 100); // Wait long enough for command response timeout before we try again
221 | // SAMConfiguration
222 | n = 0;
223 | buf[n++] = 0x01; // Normal
224 | buf[n++] = 20; // *50ms timeout
225 | buf[n++] = 0x00; // Not use IRQ
226 | if (pn532_tx (p, 0x14, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
227 | {
228 | ESP_LOGE (TAG, "SAMConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p)));
229 | return pn532_end (p);
230 | }
231 | }
232 | // GetFirmwareVersion
233 | if (pn532_tx (p, 0x02, 0, NULL, 0, NULL) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
234 | {
235 | ESP_LOGE (TAG, "GetFirmwareVersion fail %s", pn532_err_to_name (pn532_lasterr (p)));
236 | return pn532_end (p);
237 | }
238 | //uint32_t ver = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
239 | // RFConfiguration (retries)
240 | n = 0;
241 | buf[n++] = 5; // Config item 5 (MaxRetries)
242 | buf[n++] = 0xFF; // MxRtyATR (default = 0xFF)
243 | buf[n++] = 0x01; // MxRtyPSL (default = 0x01)
244 | buf[n++] = 0x01; // MxRtyPassiveActivation
245 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
246 | {
247 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p)));
248 | return pn532_end (p);
249 | }
250 | // WriteRegister
251 | n = 0;
252 | // AB are 00=open drain, 10=quasi bidi, 01=input (high imp), 11=output (push/pull)
253 | buf[n++] = 0xFF; // P3CFGA
254 | buf[n++] = 0xFC; // P3CFGA
255 | buf[n++] = (outputs & 0x3F); // Define output bits
256 | buf[n++] = 0xFF; // P3CFGB
257 | buf[n++] = 0xFD; // P3CFGB
258 | buf[n++] = 0xFF; // 0xFF
259 | buf[n++] = 0xFF; // P3
260 | buf[n++] = 0xB0; // P3
261 | buf[n++] = 0xFF; // All high
262 | buf[n++] = 0xFF; // P7CFGA
263 | buf[n++] = 0xF4; // P7CFGA
264 | buf[n++] = ((outputs >> 5) & 0x06); // Define output bits
265 | buf[n++] = 0xFF; // P7CFGB
266 | buf[n++] = 0xF5; // P7CFGB
267 | buf[n++] = 0xFF; // 0xFF
268 | buf[n++] = 0xFF; // P7
269 | buf[n++] = 0xF7; // P7
270 | buf[n++] = 0xFF; // All high
271 | if (n && (pn532_tx (p, 0x08, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0))
272 | {
273 | ESP_LOGE (TAG, "WriteRegister fail %s", pn532_err_to_name (pn532_lasterr (p)));
274 | return pn532_end (p);
275 | }
276 | // RFConfiguration
277 | n = 0;
278 | buf[n++] = 0x04; // MaxRtyCOM
279 | buf[n++] = 1; // Retries (default 0)
280 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
281 | {
282 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p)));
283 | return pn532_end (p);
284 | }
285 | // RFConfiguration
286 | n = 0;
287 | buf[n++] = 0x02; // Various timings (100*2^(n-1))us
288 | buf[n++] = 0x00; // RFU
289 | buf[n++] = 0x0B; // Default (102.4 ms)
290 | buf[n++] = 0x0A; // Default is 0x0A (51.2 ms)
291 | if (pn532_tx (p, 0x32, 0, NULL, n, buf) < 0 || pn532_rx (p, 0, NULL, sizeof (buf), buf, 50) < 0)
292 | {
293 | ESP_LOGE (TAG, "RFConfiguration fail %s", pn532_err_to_name (pn532_lasterr (p)));
294 | return pn532_end (p);
295 | }
296 | return p;
297 | }
298 |
299 | // Data access
300 | uint8_t *
301 | pn532_ats (pn532_t * p)
302 | {
303 | return p->ats;
304 | }
305 |
306 | uint8_t *
307 | pn532_nfcid (pn532_t * p, char text[21])
308 | {
309 | if (text)
310 | {
311 | char *o = text;
312 | uint8_t *i = p->nfcid;
313 | if (*i <= 10)
314 | {
315 | int len = *i++;
316 | while (len--)
317 | o += sprintf (o, "%02X", *i++);
318 | }
319 | *o++ = 0; // End
320 | }
321 | return p->nfcid;
322 | }
323 |
324 | // Low level access functions
325 | int
326 | pn532_tx_mutex (pn532_t * p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2)
327 | { // Send data to PN532
328 | if (p->pending)
329 | return -(p->lasterr = PN532_ERR_CMDPENDING);
330 | uint8_t buf[20],
331 | *b = buf;
332 | *b++ = 0x55;
333 | *b++ = 0x55;
334 | *b++ = 0x55;
335 | *b++ = 0x00; // Preamble
336 | *b++ = 0x00; // Start 1
337 | *b++ = 0xFF; // Start 2
338 | int l = len1 + len2 + 2;
339 | if (l >= 0x100)
340 | {
341 | *b++ = 0xFF; // Extended len
342 | *b++ = 0xFF;
343 | *b++ = (l >> 8); // len
344 | *b++ = (l & 0xFF);
345 | *b++ = -(l >> 8) - (l & 0xFF); // Checksum
346 | } else
347 | {
348 | *b++ = l; // Len
349 | *b++ = -l; // Checksum
350 | }
351 | *b++ = 0xD4; // Direction (host to PN532)
352 | *b++ = cmd;
353 | uint8_t sum = 0xD4 + cmd;
354 | for (l = 0; l < len1; l++)
355 | sum += data1[l];
356 | for (l = 0; l < len2; l++)
357 | sum += data2[l];
358 | uart_flush_input (p->uart);
359 | // Send data
360 | uart_tx (p, buf, b - buf);
361 | if (len1)
362 | uart_tx (p, data1, len1);
363 | if (len2)
364 | uart_tx (p, data2, len2);
365 | buf[0] = -sum; // Checksum
366 | buf[1] = 0x00; // Postamble
367 | uart_tx (p, buf, 2);
368 | uart_wait_tx_done (p->uart, 1000 / portTICK_PERIOD_MS);
369 | // Get ACK and check it
370 | l = uart_preamble (p, 50);
371 | if (l < 2)
372 | return -(p->lasterr = PN532_ERR_TIMEOUTACK);
373 | l = uart_rx (p, buf, 3, 10);
374 | if (l < 3)
375 | return -(p->lasterr = PN532_ERR_TIMEOUTACK);
376 | if (buf[2])
377 | return -(p->lasterr = PN532_ERR_BADACK);
378 | if (buf[0] == 0xFF && !buf[1])
379 | return -(p->lasterr = PN532_ERR_NACK);
380 | if (buf[0] || buf[1] != 0xFF)
381 | return -(p->lasterr = PN532_ERR_BADACK); // Bad
382 | p->pending = cmd + 1;
383 | return len1 + len2;
384 | }
385 |
386 | int
387 | pn532_tx (pn532_t * p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2)
388 | { // Send data to PN532
389 | if (!p)
390 | return -PN532_ERR_NULL;
391 | #ifdef CONFIG_PN532_DEBUG_MSG
392 | { // Messy
393 | uint8_t buf[100],
394 | *p = buf;
395 | *p++ = cmd;
396 | if (len1)
397 | {
398 | memcpy (p, data1, len1);
399 | p += len1;
400 | }
401 | if (len2)
402 | {
403 | memcpy (p, data2, len2);
404 | p += len2;
405 | }
406 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", buf, (int) (p - buf), MSGLOG);
407 | }
408 | #endif
409 | xSemaphoreTake (p->mutex, portMAX_DELAY);
410 | int l = pn532_tx_mutex (p, cmd, len1, data1, len2, data2);
411 | if (!p->pending)
412 | xSemaphoreGive (p->mutex);
413 | return l;
414 | }
415 |
416 | int
417 | pn532_rx_mutex (pn532_t * p, int max1, uint8_t * data1, int max2, uint8_t * data2, int ms)
418 | { // Recv data from PN532
419 | uint8_t pending = p->pending;
420 | p->pending = 0;
421 | int l = uart_preamble (p, ms);
422 | if (l < 2)
423 | return -(p->lasterr = PN532_ERR_TIMEOUT);
424 | uint8_t buf[9];
425 | l = uart_rx (p, buf, 4, 10);
426 | if (l < 4)
427 | return -(p->lasterr = PN532_ERR_TIMEOUT);
428 | int len = 0;
429 | if (buf[0] == 0xFF && buf[1] == 0xFF)
430 | { // Extended
431 | l = uart_rx (p, buf + 4, 3, 10);
432 | if (l < 3)
433 | return -(p->lasterr = PN532_ERR_TIMEOUT);
434 | if ((uint8_t) (buf[2] + buf[3] + buf[4]))
435 | return -(p->lasterr = PN532_ERR_HEADER); // Bad checksum
436 | len = (buf[2] << 8) + buf[3];
437 | if (buf[5] != 0xD5)
438 | return -(p->lasterr = PN532_ERR_HEADER); // Not reply
439 | if (buf[6] != pending)
440 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // Not right reply
441 | } else
442 | { // Normal
443 | if ((uint8_t) (buf[0] + buf[1]))
444 | return -(p->lasterr = PN532_ERR_HEADER); // Bad checksum
445 | len = buf[0];
446 | if (buf[2] != 0xD5)
447 | return -(p->lasterr = PN532_ERR_HEADER); // Not reply
448 | if (buf[3] != pending)
449 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // Not right reply
450 | }
451 | if (len < 2)
452 | return -(p->lasterr = PN532_ERR_HEADER); // Invalid
453 | len -= 2;
454 | int res = len;
455 | uint8_t sum = 0xD5 + pending;
456 | if (len > max1 + max2)
457 | return -(p->lasterr = PN532_ERR_SPACE); // Too big
458 | #ifdef CONFIG_PN532_DEBUG_MSG
459 | uint8_t len1 = 0,
460 | len2 = 0;
461 | #endif
462 | if (data1)
463 | {
464 | l = max1;
465 | if (l > len)
466 | l = len;
467 | if (l)
468 | {
469 | #ifdef CONFIG_PN532_DEBUG_MSG
470 | len1 = l;
471 | #endif
472 | if (uart_rx (p, data1, l, 10) < l)
473 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Bad read
474 | len -= l;
475 | while (l)
476 | sum += data1[--l];
477 | }
478 | }
479 | if (data2)
480 | {
481 | l = max2;
482 | if (l > len)
483 | l = len;
484 | if (l)
485 | {
486 | #ifdef CONFIG_PN532_DEBUG_MSG
487 | len2 = l;
488 | #endif
489 | if (uart_rx (p, data2, l, 10) < l)
490 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Bad read
491 | len -= l;
492 | while (l)
493 | sum += data2[--l];
494 | }
495 | }
496 | l = uart_rx (p, buf, 2, 10);
497 | if (l < 2)
498 | return -(p->lasterr = PN532_ERR_TIMEOUT); // Postamble
499 | if ((uint8_t) (buf[0] + sum))
500 | return -(p->lasterr = PN532_ERR_CHECKSUM); // checksum
501 | if (buf[1])
502 | return -(p->lasterr = PN532_ERR_POSTAMBLE); // postamble
503 | #ifdef CONFIG_PN532_DEBUG_MSG
504 | { // Messy
505 | uint8_t buf[100],
506 | *p = buf;
507 | *p++ = pending;
508 | if (len1)
509 | {
510 | memcpy (p, data1, len1);
511 | p += len1;
512 | }
513 | if (len2)
514 | {
515 | memcpy (p, data2, len2);
516 | p += len2;
517 | }
518 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", buf, (int) (p - buf), MSGLOG);
519 | }
520 | #endif
521 | return res;
522 | }
523 |
524 | int
525 | pn532_rx (pn532_t * p, int max1, uint8_t * data1, int max2, uint8_t * data2, int ms)
526 | { // Recv data from PN532
527 | if (!p)
528 | return -PN532_ERR_NULL;
529 | if (!p->pending)
530 | return -(p->lasterr = PN532_ERR_NOTPENDING);
531 | int l = pn532_rx_mutex (p, max1, data1, max2, data2, ms);
532 | xSemaphoreGive (p->mutex);
533 | return l;
534 | }
535 |
536 | int
537 | pn532_ready (pn532_t * p)
538 | {
539 | if (!p)
540 | return -PN532_ERR_NULL;
541 | if (!p->pending)
542 | return -(p->lasterr = PN532_ERR_NOTPENDING); // Nothing pending
543 | size_t length;
544 | if (uart_get_buffered_data_len (p->uart, &length))
545 | return -(p->lasterr = 2); // Error
546 | return length;
547 | }
548 |
549 | // Data exchange (for DESFire use)
550 | int
551 | pn532_dx (void *pv, unsigned int len, uint8_t * data, unsigned int max, const char **strerr)
552 | { // Card access function - sends to card starting CMD byte, and receives reply in to same buffer, starting status byte, returns len
553 | if (strerr)
554 | *strerr = "No error";
555 | pn532_t *p = pv;
556 | if (!p)
557 | return -PN532_ERR_NULL;
558 | if (!p->cards)
559 | return 0; // No card
560 | #ifdef CONFIG_PN532_DEBUG_DX
561 | #ifndef CONFIG_PN532_DUMP
562 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCTx", data, len, DXLOG);
563 | #endif
564 | #endif
565 | int l = pn532_tx (p, 0x40, 1, &p->tg, len, data);
566 | if (l >= 0)
567 | {
568 | uint8_t status;
569 | l = pn532_rx (p, 1, &status, max, data, 500);
570 | if (!l)
571 | l = -PN532_ERR_SHORT;
572 | else if (l >= 1 && status)
573 | l = -PN532_ERR_STATUS - status;
574 | #ifdef CONFIG_PN532_DEBUG_DX
575 | #ifndef CONFIG_PN532_DUMP
576 | if (l > 0)
577 | ESP_LOG_BUFFER_HEX_LEVEL ("NFCRx", data, l - 1, DXLOG);
578 | #endif
579 | #endif
580 | }
581 | if (l < 0)
582 | {
583 | p->lasterr = -l;
584 | #ifdef CONFIG_PN532_DEBUG_DX
585 | ESP_LOG_LEVEL (DXLOG, "NFCErr", "%s", pn532_err_to_name (p->lasterr));
586 | #endif
587 | if (strerr)
588 | *strerr = pn532_err_to_name (p->lasterr);
589 | } else
590 | l--; // Allow for status
591 | return l;
592 | }
593 |
594 | // Other higher level functions
595 | int
596 | pn532_ILPT_Send (pn532_t * p)
597 | {
598 | if (!p)
599 | return -PN532_ERR_NULL;
600 | uint8_t buf[3];
601 | // InListPassiveTarget
602 | buf[0] = 2; // 2 tags (we only report 1)
603 | buf[1] = 0; // 106 kbps type A (ISO/IEC14443 Type A)
604 | int l = pn532_tx (p, 0x4A, 2, buf, 0, NULL);
605 | if (l < 0)
606 | return l;
607 | return 0; // Waiting
608 | }
609 |
610 | int
611 | pn532_Present (pn532_t * p)
612 | {
613 | if (!p)
614 | return -PN532_ERR_NULL;
615 | uint8_t buf[1];
616 | if (!p->pending && p->cards && *p->ats && (p->ats[1] == 0x75 // DESFire
617 | //|| p->ats[1] == 0x78 // ISO
618 | ))
619 | { // We have cards, check in field still
620 | buf[0] = 6; // Test 6 Attention Request Test or ISO/IEC14443-4 card presence detection
621 | int l = pn532_tx (p, 0x00, 1, buf, 0, NULL);
622 | if (l >= 0)
623 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 110);
624 | if (l < 0)
625 | return l;
626 | if (l < 1)
627 | return -(p->lasterr = PN532_ERR_SHORT);
628 | if (!*buf)
629 | return p->cards; // Still in field
630 | }
631 | return pn532_Cards (p); // Look for card - older MIFARE need re-doing to see if present still
632 | }
633 |
634 | int
635 | pn532_deselect (pn532_t * p, uint8_t n)
636 | { // Send a release
637 | if (!p)
638 | return -PN532_ERR_NULL;
639 | uint8_t buf[2];
640 | buf[0] = n;
641 | int l = pn532_tx (p, 0x44, 1, buf, 0, NULL);
642 | if (l >= 0)
643 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 100);
644 | return l;
645 | }
646 |
647 | int
648 | pn532_release (pn532_t * p, uint8_t n)
649 | { // Send a release
650 | if (!p)
651 | return -PN532_ERR_NULL;
652 | uint8_t buf[2];
653 | buf[0] = n;
654 | int l = pn532_tx (p, 0x52, 1, buf, 0, NULL);
655 | if (l >= 0)
656 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 100);
657 | return l;
658 | }
659 |
660 | int
661 | pn532_write_GPIO (pn532_t * p, uint8_t value)
662 | { // Write P3/P7 (P72/P71 in top bits, P35-30 in rest)
663 | if (!p)
664 | return -PN532_ERR_NULL;
665 | uint8_t buf[2];
666 | buf[0] = 0x80 | (value & 0x3F);
667 | buf[1] = 0x80 | ((value >> 5) & 0x06);
668 | int l = pn532_tx (p, 0x0E, 2, buf, 0, NULL);
669 | if (l >= 0)
670 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 50);
671 | return l;
672 | }
673 |
674 | int
675 | pn532_read_GPIO (pn532_t * p)
676 | { // Read P3/P7 (P72/P71 in top bits, P35-30 in rest)
677 | if (!p)
678 | return -PN532_ERR_NULL;
679 | uint8_t buf[3];
680 | int l = pn532_tx (p, 0x0C, 0, NULL, 0, NULL);
681 | if (l >= 0)
682 | l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 50);
683 | if (l < 0)
684 | return l;
685 | if (l < 3)
686 | return -(p->lasterr = PN532_ERR_SHORT);
687 | return (buf[0] & 0x3F) | ((buf[1] & 0x06) << 5);
688 | }
689 |
690 | int
691 | pn532_Cards (pn532_t * p)
692 | { // -ve for error, else number of cards
693 | if (!p)
694 | return -PN532_ERR_NULL;
695 | uint8_t buf[100];
696 | // InListPassiveTarget to get card count and baseID
697 | if (!p->pending)
698 | pn532_ILPT_Send (p);
699 | if (p->pending != 0x4B)
700 | return -(p->lasterr = PN532_ERR_CMDMISMATCH); // We expect to be waiting for InListPassiveTarget response
701 | int l = pn532_rx (p, 0, NULL, sizeof (buf), buf, 110);
702 | if (l < 0)
703 | return l;
704 | memset (p->nfcid, 0, sizeof (p->nfcid));
705 | memset (p->ats, 0, sizeof (p->ats));
706 | // Extract first card ID
707 | uint8_t *b = buf,
708 | *e = buf + l; // end
709 | if (b >= e)
710 | return -(p->lasterr = PN532_ERR_SHORT); // No card count
711 | p->cards = *b++;
712 | if (p->cards)
713 | { // Get details of first card
714 | if (b + 5 > e)
715 | return -(p->lasterr = PN532_ERR_SPACE); // No card data
716 | p->tg = *b++;
717 | p->sens_res = (b[0] << 8) + b[1];
718 | b += 2;
719 | p->sel_res = *b++;
720 | if (b + *b + 1 > e)
721 | return -(p->lasterr = PN532_ERR_SHORT); // Too short
722 | if (*b < sizeof (p->nfcid))
723 | memcpy (p->nfcid, b, *b + 1); // OK
724 | else
725 | memset (p->nfcid, 0, sizeof (p->nfcid)); // Too big
726 | b += *b + 1;
727 | if (b < e)
728 | { // ATS
729 | if (!*b || b + *b > e)
730 | return -(p->lasterr = PN532_ERR_SHORT); // Zero or missing ATS
731 | if (*b <= sizeof (p->ats))
732 | {
733 | memcpy (p->ats, b, *b); // OK
734 | (*p->ats)--; // Make len of what follows for consistency
735 | }
736 | b += *b; // ready for second target (which we are not looking at)
737 | }
738 | }
739 | return p->cards;
740 | }
741 |
--------------------------------------------------------------------------------
/tools/.gitignore:
--------------------------------------------------------------------------------
1 | pn532test
2 |
--------------------------------------------------------------------------------
/tools/Makefile:
--------------------------------------------------------------------------------
1 | all: pn532test
2 |
3 | pn532test: pn532test.c
4 | cc -Wall -Wextra -O -o pn532test pn532test.c -I. -lpopt
5 |
--------------------------------------------------------------------------------
/tools/pn532test.c:
--------------------------------------------------------------------------------
1 | /* PN532 via serial port */
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | int debug = 0;
12 | uint8_t pending = 0;
13 |
14 | int
15 | swrite(int p, uint8_t * buf, int l)
16 | {
17 | if (debug)
18 | for (int n = 0; n < l; n++)
19 | fprintf(stderr, " %02X", buf[n]);
20 | int r = write(p, buf, l);
21 | if (r < 0)
22 | err(1, "Write failed (%d!=%d)", r, l);
23 | return r;
24 | }
25 |
26 | int
27 | sread(int p, uint8_t * buf, int l)
28 | {
29 | int q = 0;
30 | while (q < l)
31 | {
32 | fd_set f;
33 | FD_ZERO(&f);
34 | FD_SET(p, &f);
35 | struct timeval t = {0, 100000};
36 | if (select(p + 1, &f, NULL, NULL, &t) < 1)
37 | return 0;
38 | int r = read(p, buf + q, l - q);
39 | if (r <= 0)
40 | err(1, "Read failed (%d!=%d)", r, l);
41 | q += r;
42 | }
43 | if (debug)
44 | for (int n = 0; n < l; n++)
45 | fprintf(stderr, " %02X", buf[n]);
46 | return l;
47 | }
48 |
49 | int
50 | pn532_tx(int p, uint8_t cmd, int len1, uint8_t * data1, int len2, uint8_t * data2)
51 | {
52 | if (debug)
53 | fprintf(stderr, "Tx:");
54 | if (pending)
55 | return -__LINE__;
56 | uint8_t buf[20];
57 | uint8_t *b = buf;
58 | int l = len1 + len2 + 2;
59 | *b++ = 0x55;
60 | *b++ = 0x55;
61 | *b++ = 0x55;
62 | *b++ = 0x00; /* Preamble */
63 | *b++ = 0x00; /* Start 1 */
64 | *b++ = 0xFF; /* Start 2 */
65 | if (l >= 0x100)
66 | {
67 | *b++ = 0xFF;
68 | /* Extended len */
69 | *b++ = 0xFF;
70 | *b++ = (l >> 8);
71 | /* len */
72 | *b++ = (l & 0xFF);
73 | *b++ = -(l >> 8) - (l & 0xFF);
74 | /* Checksum */
75 | } else
76 | {
77 | *b++ = l;
78 | /* Len */
79 | *b++ = -l;
80 | /* Checksum */
81 | }
82 | *b++ = 0xD4;
83 | /* Direction(host to PN532) */
84 | *b++ = cmd;
85 | uint8_t sum = 0xD4 + cmd;
86 | for (l = 0; l < len1; l++)
87 | sum += data1[l];
88 | for (l = 0; l < len2; l++)
89 | sum += data2[l];
90 | /* Send data */
91 | swrite(p, buf, b - buf);
92 | if (len1)
93 | write(p, data1, len1);
94 | if (len2)
95 | swrite(p, data2, len2);
96 | buf[0] = -sum;
97 | /* Checksum */
98 | buf[1] = 0x00;
99 | /* Postamble */
100 | swrite(p, buf, 2);
101 | if (debug)
102 | fprintf(stderr, "\nRx:");
103 | /* Get ACK and check it */
104 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0x00);
105 | if (l <= 0)
106 | return -__LINE__;
107 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0xFF);
108 | if (l <= 0)
109 | return -__LINE__;
110 | l = sread(p, buf, 3);
111 | if (l < 3)
112 | return -__LINE__;
113 | if (buf[2])
114 | return -__LINE__;
115 | if (buf[0] == 0xFF && !buf[1])
116 | return -__LINE__;
117 | if (buf[0] || buf[1] != 0xFF)
118 | return -__LINE__;
119 | pending = cmd + 1; /* Expected reply */
120 | if (debug)
121 | fprintf(stderr, "\n");
122 | return len1 + len2;
123 | }
124 |
125 | int
126 | pn532_rx(int p, int max1, uint8_t * data1, int max2, uint8_t * data2)
127 | {
128 | if (debug)
129 | fprintf(stderr, "Rx:");
130 | if (!pending)
131 | return -__LINE__;
132 | uint8_t expect = pending;
133 | pending = 0;
134 | /* Recv data from PN532 */
135 | uint8_t buf[9];
136 | int l;
137 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0x00);
138 | if (l <= 0)
139 | return -__LINE__;
140 | while ((l = sread(p, buf, 1)) == 1 && *buf != 0xFF);
141 | if (l <= 0)
142 | return -__LINE__;
143 | l = sread(p, buf, 4);
144 | if (l < 4)
145 | return -__LINE__;
146 | int len = 0;
147 | if (buf[0] == 0xFF && buf[1] == 0xFF)
148 | { /* Extended */
149 | l = sread(p, buf + 4, 3);
150 | if (l < 3)
151 | return -__LINE__;
152 | if ((uint8_t) (buf[2] + buf[3] + buf[4]))
153 | return -__LINE__;
154 | len = (buf[2] << 8) + buf[3];
155 | if (buf[5] != 0xD5)
156 | return -__LINE__;
157 | if (buf[6] != expect)
158 | return -__LINE__;
159 | } else
160 | { /* Normal */
161 | if ((uint8_t) (buf[0] + buf[1]))
162 | return -__LINE__;
163 | len = buf[0];
164 | if (buf[2] != 0xD5)
165 | return -__LINE__;
166 | if (buf[3] != expect)
167 | return -__LINE__;
168 | }
169 | if (len < 2)
170 | return -__LINE__;
171 | len -= 2;
172 | int res = len;
173 | uint8_t sum = 0xD5 + expect;
174 | if (len > max1 + max2)
175 | return -__LINE__;
176 | if (data1)
177 | {
178 | l = max1;
179 | if (l > len)
180 | l = len;
181 | if (l)
182 | {
183 | if (sread(p, data1, l) < l)
184 | return -__LINE__;
185 | len -= l;
186 | while (l)
187 | sum += data1[--l];
188 | }
189 | }
190 | if (data2)
191 | {
192 | l = max2;
193 | if (l > len)
194 | l = len;
195 | if (l)
196 | {
197 | if (sread(p, data2, l) < l)
198 | return -__LINE__;
199 | len -= l;
200 | while (l)
201 | sum += data2[--l];
202 | }
203 | }
204 | l = sread(p, buf, 2);
205 | if (l < 2)
206 | return -__LINE__;
207 | if ((uint8_t) (buf[0] + sum))
208 | return -__LINE__;
209 | if (buf[1])
210 | return -__LINE__;
211 | if (debug)
212 | fprintf(stderr, "\n");
213 | return res;
214 | }
215 | int
216 | main(int argc, const char *argv[])
217 | {
218 | const char *port = NULL;
219 | { /* POPT */
220 | poptContext optCon;
221 | const struct poptOption optionsTable[] = {
222 | {"port", 'p', POPT_ARG_STRING, &port, 0, "Port", "/dev/cu.usbserial..."},
223 | {"debug", 'v', POPT_ARG_NONE, &debug, 0, "Debug", 0},
224 | POPT_AUTOHELP {}
225 | };
226 |
227 | optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
228 |
229 | int c;
230 | if ((c = poptGetNextOpt(optCon)) < -1)
231 | errx(1, "%s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c));
232 |
233 | if (!port && poptPeekArg(optCon))
234 | port = poptGetArg(optCon);
235 |
236 | if (!port || poptPeekArg(optCon))
237 | {
238 | poptPrintUsage(optCon, stderr, 0);
239 | return -1;
240 | }
241 | poptFreeContext(optCon);
242 | }
243 | int p = open(port, O_RDWR);
244 | if (p < 0)
245 | err(1, "Cannot open %s", port);
246 | struct termios t;
247 | if (tcgetattr(p, &t) < 0)
248 | err(1, "Cannot get termios");
249 | cfsetspeed(&t, 115200); /* The default HSU baud rate */
250 | if (tcsetattr(p, TCSANOW, &t) < 0)
251 | err(1, "Cannot set termios");
252 | usleep(100000);
253 | tcflush(p, TCIOFLUSH);
254 |
255 | uint8_t buf[300];
256 | int n,
257 | l;
258 | while (1)
259 | {
260 | /* SAM config */
261 | n = 0;
262 | buf[n++] = 0x01; /* Normal */
263 | buf[n++] = 20; /* *50 ms timeout */
264 | buf[n++] = 0x01; /* Use IRQ */
265 | if ((l = pn532_tx(p, 0x14, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0)
266 | warnx("GetFirmwareVersion fail (%d)", -l);
267 | else
268 | break;
269 | }
270 | /* RFConfiguration */
271 | n = 0;
272 | buf[n++] = 5; /* Config item 5(MaxRetries) */
273 | buf[n++] = 0xFF; /* MxRtyATR(default = 0xFF) */
274 | buf[n++] = 0x01; /* MxRtyPSL(default = 0x01) */
275 | buf[n++] = 0x01; /* MxRtyPassiveActivation */
276 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0)
277 | errx(1, "RFConfiguration fail (%d)", -l);
278 | /* RFConfiguration */
279 | n = 0;
280 | buf[n++] = 0x04; /* MaxRtyCOM */
281 | buf[n++] = 1; /* Retries (default 0) */
282 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0)
283 | errx(1, "RFConfiguration fail (%d)", -l);
284 | /* RFConfiguration */
285 | n = 0;
286 | buf[n++] = 0x02; /* Various timings (100*2^(n-1))us */
287 | buf[n++] = 0x00; /* RFU */
288 | buf[n++] = 0x0B; /* Default (102.4 ms) */
289 | buf[n++] = 0x0A; /* Default is 0x0A (51.2 ms) */
290 | if ((l = pn532_tx(p, 0x32, 0, NULL, n, buf)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0)
291 | errx(1, "RFConfiguration fail (%d)", -l);
292 |
293 | while (1)
294 | {
295 | /* InListPassiveTarget */
296 | buf[0] = 2; /* 2 tags(we only report 1) */
297 | buf[1] = 0; /* 106 kbps type A(ISO / IEC14443 Type A) */
298 | if ((l = pn532_tx(p, 0x4A, 2, buf, 0, NULL)) < 0 || (l = pn532_rx(p, 0, NULL, sizeof(buf), buf)) < 0)
299 | if (l < 0)
300 | warnx("Bad ILPT (%d)", -l);
301 | if (l > 1)
302 | {
303 | //Found a card
304 | fprintf(stderr, "Card:");
305 | for (int n = 0; n < l; n++)
306 | fprintf(stderr, " %02X", buf[n]);
307 | fprintf(stderr, "\n");
308 | }
309 | }
310 |
311 | close(p);
312 | return 0;
313 | }
314 |
--------------------------------------------------------------------------------